Skip to content

Commit

Permalink
Merge branch 'develop' into remove-col-factor
Browse files Browse the repository at this point in the history
  • Loading branch information
prateek105 committed Dec 12, 2023
2 parents 13c8f50 + 912b1f6 commit fd28899
Show file tree
Hide file tree
Showing 43 changed files with 955 additions and 1,030 deletions.
2 changes: 1 addition & 1 deletion src/PoolInfoUtils.sol
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,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_);

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 @@ -59,7 +59,8 @@ import {
_revertIfAuctionDebtLocked,
_revertIfAuctionClearable,
_revertAfterExpiry,
_revertIfAuctionPriceBelow
_revertIfAuctionPriceBelow,
_revertIfActiveAuctions
} from '../libraries/helpers/RevertsHelper.sol';

import { Buckets } from '../libraries/internal/Buckets.sol';
Expand Down Expand Up @@ -159,7 +160,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 @@ -195,7 +196,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 @@ -399,7 +400,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 @@ -909,7 +910,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
8 changes: 4 additions & 4 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
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 @@ -337,7 +337,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
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
12 changes: 6 additions & 6 deletions tests/forge/interactions/ERC721TakeWithExternalLiquidity.sol
Original file line number Diff line number Diff line change
Expand Up @@ -80,14 +80,14 @@ contract ERC721TakeWithExternalLiquidityTest is ERC721HelperContract {
// call take using taker contract
bytes memory data = abi.encode(address(_pool));
vm.expectEmit(true, true, false, true);
uint256 quoteTokenPaid = 1_082.785034492073132320 * 1e18;
uint256 quoteTokenPaid = 1_126.096435871756057616 * 1e18;
uint256 collateralPurchased = 2 * 1e18;
uint256 bondChange = 12.105904710718649453 * 1e18;
uint256 bondChange = 12.590140899147395432 * 1e18;
emit Take(_borrower, quoteTokenPaid, collateralPurchased, bondChange, true);
_pool.take(_borrower, 2, address(taker), data);

// confirm we earned some quote token
assertEq(_quote.balanceOf(address(taker)), 417.214965507926867680 * 1e18);
assertEq(_quote.balanceOf(address(taker)), 373.903564128243942384 * 1e18);
}

function testTakeNFTCalleeDiffersFromSender() external {
Expand All @@ -110,14 +110,14 @@ contract ERC721TakeWithExternalLiquidityTest is ERC721HelperContract {
changePrank(_lender);
bytes memory data = abi.encode(address(_pool));
vm.expectEmit(true, true, false, true);
uint256 quoteTokenPaid = 1_082.785034492073132320 * 1e18;
uint256 quoteTokenPaid = 1_126.096435871756057616 * 1e18;
uint256 collateralPurchased = 2 * 1e18;
uint256 bondChange = 12.105904710718649453 * 1e18;
uint256 bondChange = 12.590140899147395432 * 1e18;
emit Take(_borrower, quoteTokenPaid, collateralPurchased, bondChange, true);
_pool.take(_borrower, 2, address(taker), data);

// _lender is msg.sender, QT & CT balances post take
assertEq(_quote.balanceOf(_lender), 48_895.437905421641180379 * 1e18);
assertEq(_quote.balanceOf(_lender), 48_852.126504041958255083 * 1e18);
assertEq(_quote.balanceOf(address(taker)), 1_500.0 * 1e18); // QT is increased as NFTTakeExample contract sells the NFT
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,6 @@ abstract contract UnboundedRewardsPoolHandler is UnboundedPositionPoolHandler {
err == keccak256(abi.encodeWithSignature("AlreadyClaimed()")) ||
err == keccak256(abi.encodeWithSignature("EpochNotAvailable()")) ||
err == keccak256(abi.encodeWithSignature("InsufficientLiquidity()")) ||
err == keccak256(abi.encodeWithSignature("MoveStakedLiquidityInvalid()")) ||
err == keccak256(abi.encodeWithSignature("NotAjnaPool()")) ||
err == keccak256(abi.encodeWithSignature("NotOwnerOfDeposit()")) ||
err == keccak256(abi.encodeWithSignature("DeployWithZeroAddress()")),
Expand Down
Loading

0 comments on commit fd28899

Please sign in to comment.