Platform: Code4rena
Start Date: 08/09/2023
Pot Size: $70,000 USDC
Total HM: 8
Participants: 84
Period: 6 days
Judge: gzeon
Total Solo HM: 2
Id: 285
League: ETH
Rank: 49/84
Findings: 1
Award: $50.43
🌟 Selected for report: 0
🚀 Solo Findings: 0
50.4324 USDC - $50.43
https://github.com/code-423n4/2023-09-centrifuge/blob/512e7a71ebd9ae76384f837204216f26380c9f91/src/InvestmentManager.sol#L248-L251 https://github.com/code-423n4/2023-09-centrifuge/blob/512e7a71ebd9ae76384f837204216f26380c9f91/src/InvestmentManager.sol#L427-L441 https://github.com/code-423n4/2023-09-centrifuge/blob/512e7a71ebd9ae76384f837204216f26380c9f91/src/InvestmentManager.sol#L579-L581 https://github.com/code-423n4/2023-09-centrifuge/blob/512e7a71ebd9ae76384f837204216f26380c9f91/src/InvestmentManager.sol#L598-L600 https://github.com/code-423n4/2023-09-centrifuge/blob/512e7a71ebd9ae76384f837204216f26380c9f91/src/InvestmentManager.sol#L474-L477
When a user attempts to process a deposit, more tranche tokens than maxMint
may be sent to that user.
If there are not enough tranche tokens
in 'escrow', the transaction may be cancelled.
X
: amount of asset token(LP currency)
(maxDeposit
)
Y
: amount of tranche token
(maxMint
)
Price(our calculation) <= X / Y
(due to rounding)
So when a user attempts to process a deposit with his whole maxDeposit
,
required amount of 'tranch token' = X / Price >= X / (X / Y) = Y
Let me take example.
Let's assume that currencyDecimals = 18, trancheTokenDecimals = 18
.
And a user requested deposit with 1 * 10 ^ 18
assets.
In the next epoch, a user received message from Centrifuge and inside handleExecutedCollectInvest()
function, his maxDeposit
and maxMint
were increased and let's suppose that he received currencyPayout = 1 * 10 ^ 18, trancheTokensPayout = 3 * 10 ^ 18
lpValues.maxDeposit = lpValues.maxDeposit + currencyPayout; lpValues.maxMint = lpValues.maxMint + trancheTokensPayout; LiquidityPoolLike(liquidityPool).mint(address(escrow), trancheTokensPayout);
And 3 * 10 ^ 18 tranche tokens
was minted to escrow
.
That user wanted to process deposit with his whole maxDepsit
(1 * 10 ^ 18
in this case).
In _calculatePrice()
function,
depositPrice = currencyAmountInPriceDecimals.mulDiv( 10 ** PRICE_DECIMALS, trancheTokenAmountInPriceDecimals, MathLib.Rounding.Down ) = 1 * 10 ^ 18 * 10 ^ 18 / (3 * 10 ^ 18) = 333,333,333,333,333,333
In _calculateTrancheTokenAmount()
function,
uint256 currencyAmountInPriceDecimals = _toPriceDecimals(currencyAmount, currencyDecimals, liquidityPool).mulDiv(10 ** PRICE_DECIMALS, price, MathLib.Rounding.Down) = 1 * 10 ^ 18 * 10 ^ 18 / 333,333,333,333,333,333 = 3,000,000,000,000,000,003
This value is larger than maxMint = 3 * 10 ^ 18
.
If escrow
has not enough tranche token
, user couldn't process deposit.
Manual audit https://www.calculator.net/big-number-calculator.html (for calculation)
In _deposit()
function, we can select smaller value between maxMint
and trancheTokenAmount
.
Error
#0 - c4-pre-sort
2023-09-15T20:39:45Z
raymondfam marked the issue as duplicate of #118
#1 - c4-pre-sort
2023-09-15T20:39:51Z
raymondfam marked the issue as sufficient quality report
#2 - c4-judge
2023-09-25T13:30:07Z
gzeon-c4 marked the issue as not a duplicate
#3 - c4-judge
2023-09-25T13:30:19Z
gzeon-c4 marked the issue as duplicate of #34
#4 - c4-judge
2023-09-26T18:11:25Z
gzeon-c4 marked the issue as satisfactory