Skip to content

Commit

Permalink
merge latest
Browse files Browse the repository at this point in the history
  • Loading branch information
Mike committed Dec 14, 2023
2 parents 0677227 + d4d9602 commit 9a49e21
Show file tree
Hide file tree
Showing 46 changed files with 1,588 additions and 1,049 deletions.
2 changes: 1 addition & 1 deletion src/PoolInfoUtils.sol
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ contract PoolInfoUtils {
uint256 npTpRatio;
(t0Debt, collateral_, npTpRatio) = pool.borrowerInfo(borrower_);

t0Np_ = collateral_ == 0 ? 0 : Math.mulDiv(t0Debt, npTpRatio, collateral_);
t0Np_ = collateral_ == 0 ? 0 : Math.mulDiv(Maths.wmul(t0Debt, COLLATERALIZATION_FACTOR), npTpRatio, collateral_);
t0ThresholdPrice_ = collateral_ == 0 ? 0 : Maths.wdiv(t0Debt, collateral_);

debt_ = Maths.ceilWmul(t0Debt, pendingInflator);
Expand Down
4 changes: 1 addition & 3 deletions src/PositionManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -591,9 +591,7 @@ contract PositionManager is PermitERC721, IPositionManager, Multicall, Reentranc
collateralTokenSymbol: tokenSymbol(collateralTokenAddress),
quoteTokenSymbol: tokenSymbol(quoteTokenAddress),
tokenId: tokenId_,
pool: pool,
owner: ownerOf(tokenId_),
indexes: tokenInfo.positionIndexes.values()
owner: ownerOf(tokenId_)
});

return PositionNFTSVG.constructTokenURI(params);
Expand Down
11 changes: 6 additions & 5 deletions src/base/Pool.sol
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ import {
_revertIfAuctionDebtLocked,
_revertIfAuctionClearable,
_revertAfterExpiry,
_revertIfAuctionPriceBelow
_revertIfAuctionPriceBelow,
_revertIfActiveAuctions
} from '../libraries/helpers/RevertsHelper.sol';

import { Buckets } from '../libraries/internal/Buckets.sol';
Expand Down Expand Up @@ -160,7 +161,7 @@ abstract contract Pool is Clone, ReentrancyGuard, Multicall, IPool {

_revertIfAuctionClearable(auctions, loans);

_revertIfAuctionPriceBelow(index_, auctions);
_revertIfAuctionPriceBelow(auctions, index_);

PoolState memory poolState = _accruePoolInterest();

Expand Down Expand Up @@ -196,7 +197,7 @@ abstract contract Pool is Clone, ReentrancyGuard, Multicall, IPool {

_revertIfAuctionClearable(auctions, loans);

_revertIfAuctionPriceBelow(toIndex_, auctions);
_revertIfAuctionPriceBelow(auctions, toIndex_);

PoolState memory poolState = _accruePoolInterest();

Expand Down Expand Up @@ -400,7 +401,7 @@ abstract contract Pool is Clone, ReentrancyGuard, Multicall, IPool {
* @dev - `KickReserveAuction`
*/
function kickReserveAuction() external override nonReentrant {
_revertIfAuctionClearable(auctions, loans);
_revertIfActiveAuctions(auctions);

// start a new claimable reserve auction, passing in relevant parameters such as the current pool size, debt, balance, and inflator value
KickerActions.kickReserveAuction(
Expand Down Expand Up @@ -910,7 +911,7 @@ abstract contract Pool is Clone, ReentrancyGuard, Multicall, IPool {
Loan memory loan = Loans.getByIndex(loans, loanId_);
return (
loan.borrower,
loan.thresholdPrice
Maths.wmul(loan.thresholdPrice, COLLATERALIZATION_FACTOR)
);
}

Expand Down
15 changes: 0 additions & 15 deletions src/interfaces/pool/commons/IPoolErrors.sol
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,6 @@ interface IPoolErrors {
*/
error AddAboveAuctionPrice();

/**
* @notice `LP` allowance is already set by the owner.
*/
error AllowanceAlreadySet();

/**
* @notice The action cannot be executed on an active auction.
*/
Expand Down Expand Up @@ -143,11 +138,6 @@ interface IPoolErrors {
*/
error LUPBelowHTP();

/**
* @notice Liquidation must result in `LUP` below the borrowers threshold price.
*/
error LUPGreaterThanTP();

/**
* @notice From index and to index arguments to move are the same.
*/
Expand Down Expand Up @@ -184,11 +174,6 @@ interface IPoolErrors {
*/
error NoDebt();

/**
* @notice Borrower is attempting to borrow an amount of quote tokens that will push the pool into under-collateralization.
*/
error PoolUnderCollateralized();

/**
* @notice Actor is attempting to kick with bucket price below the `LUP`.
*/
Expand Down
1 change: 0 additions & 1 deletion src/interfaces/pool/commons/IPoolInternals.sol
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ struct KickResult {
uint256 amountToCoverBond; // [WAD] amount of bond that needs to be covered
uint256 t0KickedDebt; // [WAD] new t0 debt after kick
uint256 collateralPreAction; // [WAD] The amount of borrower collateral before kick, same as the one after kick
uint256 poolDebt; // [WAD] current debt in pool after kick
uint256 lup; // [WAD] current LUP in pool after kick
}

Expand Down
2 changes: 1 addition & 1 deletion src/interfaces/pool/commons/IPoolSettlerActions.sol
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ interface IPoolSettlerActions {
* @param borrowerAddress_ Address of the auctioned borrower.
* @param maxDepth_ Measured from `HPB`, maximum number of buckets deep to settle debt.
* @return collateralSettled_ Amount of collateral settled.
* @return isBorrowerSettled_ Is all borrower's debt is settled.
* @return isBorrowerSettled_ True if all borrower's debt is settled.
* @dev `maxDepth_` is used to prevent unbounded iteration clearing large liquidations.
*/
function settle(
Expand Down
14 changes: 7 additions & 7 deletions src/interfaces/pool/commons/IPoolState.sol
Original file line number Diff line number Diff line change
Expand Up @@ -200,9 +200,9 @@ interface IPoolState {

/**
* @notice Returns information about a loan in the pool.
* @param loanId_ Loan's id within loan heap. Max loan is position `1`.
* @return borrower_ Borrower address at the given position.
* @return thresholdPrice_ Borrower threshold price in pool.
* @param loanId_ Loan's id within loan heap. Max loan is position `1`.
* @return borrower_ Borrower address at the given position.
* @return t0ThresholdPrice_ Borrower t0 threshold price in pool.
*/
function loanInfo(
uint256 loanId_
Expand All @@ -211,7 +211,7 @@ interface IPoolState {
view
returns (
address borrower_,
uint256 thresholdPrice_
uint256 t0ThresholdPrice_
);

/**
Expand Down Expand Up @@ -386,9 +386,9 @@ struct Loan {

/// @dev Struct holding borrower state.
struct Borrower {
uint256 t0Debt; // [WAD] Borrower debt time-adjusted as if it was incurred upon first loan of pool.
uint256 collateral; // [WAD] Collateral deposited by borrower.
uint256 npTpRatio; // [WAD] Np to Tp ratio at the time of last borrow or pull collateral.
uint256 t0Debt; // [WAD] Borrower debt time-adjusted as if it was incurred upon first loan of pool.
uint256 collateral; // [WAD] Collateral deposited by borrower.
uint256 npTpRatio; // [WAD] Np to Tp ratio at the time of last borrow or pull collateral.
}

/**********************/
Expand Down
5 changes: 0 additions & 5 deletions src/interfaces/rewards/IRewardsManagerErrors.sol
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,6 @@ interface IRewardsManagerErrors {
*/
error InsufficientLiquidity();

/**
* @notice User provided move index params that didn't match in size.
*/
error MoveStakedLiquidityInvalid();

/**
* @notice User attempted to update exchange rates for a pool that wasn't deployed by an `Ajna` factory.
*/
Expand Down
12 changes: 0 additions & 12 deletions src/interfaces/rewards/IRewardsManagerEvents.sol
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,6 @@ interface IRewardsManagerEvents {
uint256 amount
);

/**
* @notice Emitted when moves liquidity in a staked `NFT` between buckets.
* @param tokenId `ID` of the staked `NFT`.
* @param fromIndexes Array of indexes from which liquidity was moved.
* @param toIndexes Array of indexes to which liquidity was moved.
*/
event MoveStakedLiquidity(
uint256 tokenId,
uint256[] fromIndexes,
uint256[] toIndexes
);

/**
* @notice Emitted when lender stakes their `LP` `NFT` in the rewards contract.
* @param owner Owner of the staked `NFT`.
Expand Down
2 changes: 0 additions & 2 deletions src/libraries/external/BorrowerActions.sol
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ library BorrowerActions {
struct DrawDebtLocalVars {
bool borrow; // true if borrow action
uint256 borrowerDebt; // [WAD] borrower's accrued debt
uint256 compensatedCollateral; // [WAD] amount of borrower collateral that is compensated with LP (NFTs only)
uint256 t0BorrowAmount; // [WAD] t0 amount to borrow
uint256 t0DebtChange; // [WAD] additional t0 debt resulted from draw debt action
bool pledge; // true if pledge action
Expand All @@ -56,7 +55,6 @@ library BorrowerActions {
/// @dev Struct used for `repayDebt` function local vars.
struct RepayDebtLocalVars {
uint256 borrowerDebt; // [WAD] borrower's accrued debt
uint256 compensatedCollateral; // [WAD] amount of borrower collateral that is compensated with LP (NFTs only)
bool pull; // true if pull action
bool repay; // true if repay action
bool stampNpTpRatio; // true if loan's Np to Tp ratio should be restamped (when repay settles auction or pull collateral)
Expand Down
3 changes: 2 additions & 1 deletion src/libraries/external/KickerActions.sol
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,8 @@ library KickerActions {
// neutral price = Tp * Np to Tp ratio
// neutral price is capped at 50 * max pool price
vars.neutralPrice = Maths.min(
Math.mulDiv(vars.borrowerDebt, vars.borrowerNpTpRatio, vars.borrowerCollateral),
Math.mulDiv(Maths.wmul(vars.borrowerDebt, COLLATERALIZATION_FACTOR),
vars.borrowerNpTpRatio, vars.borrowerCollateral),
MAX_INFLATED_PRICE
);
// check if NP is not less than price at the limit index provided by the kicker - done to prevent frontrunning kick auction call with a large amount of loan
Expand Down
3 changes: 1 addition & 2 deletions src/libraries/external/LenderActions.sol
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@ import {
_depositFeeRate,
_htp,
_priceAt,
MAX_FENWICK_INDEX,
COLLATERALIZATION_FACTOR
MAX_FENWICK_INDEX
} from '../helpers/PoolHelper.sol';

import { Deposits } from '../internal/Deposits.sol';
Expand Down
10 changes: 3 additions & 7 deletions src/libraries/external/PoolCommons.sol
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,7 @@ import {
_htp,
_indexOf,
MAX_FENWICK_INDEX,
MIN_PRICE, MAX_PRICE,
COLLATERALIZATION_FACTOR
MIN_PRICE, MAX_PRICE
} from '../helpers/PoolHelper.sol';

import { Deposits } from '../internal/Deposits.sol';
Expand Down Expand Up @@ -467,10 +466,7 @@ library PoolCommons {
return (
Maths.ceilWmul(
t0Debt,
Maths.wmul(
inflator,
PRBMathUD60x18.exp((interestState_.interestRate * (block.timestamp - inflatorState_.inflatorUpdate)) / 365 days)
)
pendingInflator(inflator, inflatorState_.inflatorUpdate, interestState_.interestRate)
),
Maths.ceilWmul(t0Debt, inflator),
Maths.ceilWmul(poolBalances_.t0DebtInAuction, inflator),
Expand Down Expand Up @@ -502,7 +498,7 @@ library PoolCommons {
uint256 inflator_,
uint256 inflatorUpdate,
uint256 interestRate_
) external view returns (uint256) {
) public view returns (uint256) {
return Maths.wmul(
inflator_,
PRBMathUD60x18.exp((interestRate_ * (block.timestamp - inflatorUpdate)) / 365 days)
Expand Down
2 changes: 0 additions & 2 deletions src/libraries/external/PositionNFTSVG.sol
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,7 @@ library PositionNFTSVG {
string collateralTokenSymbol; // the symbol of collateral token of the pool
string quoteTokenSymbol; // the symbol of quote token of the pool
uint256 tokenId; // the ID of positions NFT token
address pool; // the address of pool tracked in positions NFT token
address owner; // the owner of positions NFT token
uint256[] indexes; // the array of price buckets index with LP to be tracked by the NFT
}

/*******************************/
Expand Down
18 changes: 8 additions & 10 deletions src/libraries/external/TakerActions.sol
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,6 @@ library TakerActions {
uint256 bucketScale; // [WAD] The bucket scale.
uint256 collateralAmount; // [WAD] The amount of collateral taken.
uint256 excessQuoteToken; // [WAD] Difference of quote token that borrower receives after take (for fractional NFT only)
uint256 factor; // The take factor, calculated based on bond penalty factor.
bool isRewarded; // True if kicker is rewarded (auction price lower than neutral price), false if penalized (auction price greater than neutral price).
address kicker; // Address of auction kicker.
uint256 quoteTokenAmount; // [WAD] Scaled quantity in Fenwick tree and before 1-bpf factor, paid for collateral
Expand Down Expand Up @@ -370,14 +369,6 @@ library TakerActions {

_rewardTake(auctions_, liquidation, vars_);

emit Take(
params_.borrower,
vars_.quoteTokenAmount,
vars_.collateralAmount,
vars_.bondChange,
vars_.isRewarded
);

if (params_.poolType == uint8(PoolType.ERC721)) {
// slither-disable-next-line divide-before-multiply
uint256 collateralTaken = (vars_.collateralAmount / 1e18) * 1e18; // solidity rounds down, so if 2.5 it will be 2.5 / 1 = 2
Expand All @@ -398,6 +389,14 @@ library TakerActions {
}
}
}

emit Take(
params_.borrower,
vars_.quoteTokenAmount,
vars_.collateralAmount,
vars_.bondChange,
vars_.isRewarded
);
}

/**
Expand Down Expand Up @@ -705,7 +704,6 @@ library TakerActions {
liquidation_.bondFactor,
bucketPrice_ == 0 ? vars.auctionPrice : bucketPrice_
);
vars.factor = uint256(1e18 - Maths.maxInt(0, vars.bpf));
vars.kicker = liquidation_.kicker;
vars.isRewarded = (vars.bpf >= 0);
}
Expand Down
20 changes: 16 additions & 4 deletions src/libraries/helpers/RevertsHelper.sol
Original file line number Diff line number Diff line change
Expand Up @@ -76,16 +76,16 @@ import { Maths } from '../internal/Maths.sol';
if (newPrice_ < _priceAt(limitIndex_)) revert LimitIndexExceeded();
}

/**
/**
* @notice Check if provided price is above current auction price.
* @notice Prevents manipulative deposits and arbTakes.
* @dev Reverts with `AddAboveAuctionPrice` if price is above head of auction queue.
* @param index_ Identifies bucket price to be compared with current auction price.
* @param auctions_ Auctions data.
* @param index_ Identifies bucket price to be compared with current auction price.
*/
function _revertIfAuctionPriceBelow(
uint256 index_,
AuctionsState storage auctions_
AuctionsState storage auctions_,
uint256 index_
) view {
address head = auctions_.head;
if (head != address(0)) {
Expand All @@ -94,6 +94,18 @@ import { Maths } from '../internal/Maths.sol';
}
}

/**
* @notice Check if there are still active / non settled auctions in pool.
* @notice Prevents kicking reserves auctions until all pending auctions are fully settled.
* @dev Reverts with `AuctionNotCleared`.
* @param auctions_ Auctions data.
*/
function _revertIfActiveAuctions(
AuctionsState storage auctions_
) view {
if (auctions_.noOfAuctions != 0) revert AuctionNotCleared();
}

/**
* @notice Check if expiration provided by user has met or exceeded current block height timestamp.
* @notice Prevents stale transactions interacting with the pool at potentially unfavorable prices.
Expand Down
2 changes: 1 addition & 1 deletion tests/forge/interactions/BalancerUniswapExample.sol
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ contract BalancerUniswapTaker {

// take auction from Ajna pool, give USDC, receive WETH
IAjnaPool(decoded.ajnaPool).take(decoded.borrower, decoded.maxAmount, address(this), new bytes(0));
uint256 usdcBalanceAfterTake = 81974358;
uint256 usdcBalanceAfterTake = 81253332;
assert(tokens[0].balanceOf(address(this)) == usdcBalanceAfterTake); // USDC balance after Ajna take
assert(tokens[1].balanceOf(address(this)) == 2000000000000000000); // WETH balance after Ajna take

Expand Down
6 changes: 3 additions & 3 deletions tests/forge/interactions/ERC20TakeWithExternalLiquidity.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ contract ERC20TakeWithExternalLiquidityTest is Test {
})
);
vm.expectEmit(true, true, false, true);
emit Take(_borrower, 18.025641486856350208 * 1e18, 2.0 * 1e18, 0.201532798513255896 * 1e18, true);
emit Take(_borrower, 18.746667146330604216 * 1e18, 2.0 * 1e18, 0.209594110453786132 * 1e18, true);
taker.take(tokens, amounts, data);

assertGt(usdc.balanceOf(address(this)), 0); // could vary
Expand All @@ -126,7 +126,7 @@ contract ERC20TakeWithExternalLiquidityTest is Test {
// call take using taker contract
bytes memory data = abi.encode(address(_ajnaPool));
vm.expectEmit(true, true, false, true);
emit Take(_borrower, 18.025641486856350208 * 1e18, 2.0 * 1e18, 0.201532798513255896 * 1e18, true);
emit Take(_borrower, 18.746667146330604216 * 1e18, 2.0 * 1e18, 0.209594110453786132 * 1e18, true);
_ajnaPool.take(_borrower, takeAmount, address(taker), data);

// confirm we earned some quote token
Expand All @@ -148,7 +148,7 @@ contract ERC20TakeWithExternalLiquidityTest is Test {
_ajnaPool.take(_borrower, 1_001 * 1e18, _lender1, new bytes(0));

// _lender is has QT deducted from balance
assertEq(usdc.balanceOf(_lender), 119_999.999999926981758794 * 1e18);
assertEq(usdc.balanceOf(_lender), 119_999.999999926981037768 * 1e18);
assertEq(weth.balanceOf(_lender), 0);

// callee, _lender1 receives CT from take
Expand Down
Loading

0 comments on commit 9a49e21

Please sign in to comment.