Platform: Code4rena
Start Date: 21/08/2023
Pot Size: $36,500 USDC
Total HM: 1
Participants: 43
Period: 7 days
Judge: Dravee
Id: 277
League: ETH
Rank: 8/43
Findings: 1
Award: $1,933.59
🌟 Selected for report: 0
🚀 Solo Findings: 0
1933.5938 USDC - $1,933.59
https://github.com/code-423n4/2023-08-shell/blob/main/src/proteus/EvolvingProteus.sol#L563-#L595
EvolvingProteus defines a price range using 2 constants, MAX_M
and MIN_M
:
int128 constant MAX_M = 0x5f5e1000000000000000000; int128 constant MIN_M = 0x00000000000002af31dc461;
These constants are used in _checkBalances
to make sure the ratio of x reserve
and y reserve tokens must be within [MIN_M, MAX_M):
function _checkBalances(int256 x, int256 y) private pure { if (x < MIN_BALANCE || y < MIN_BALANCE) revert BalanceError(x,y); int128 finalBalanceRatio = y.divi(x); if (finalBalanceRatio < MIN_M) revert BoundaryError(x,y); else if (MAX_M <= finalBalanceRatio) revert BoundaryError(x,y); }
However, function _reserveTokenSpecified
does not call this function to verify the ratio, _reserveTokenSpecified
is used in depositGivenInputAmount
and withdrawGivenOutputAmount
. So if a user deposit or withdraw tokens using these functions, the ratio could go out of bound.
Below is a POC for this issue, place this in file test/EvolvingProteusProperties.t.sol
under contract EvolvingProteusProperties
and run it using command:
forge test --match-path src/test/EvolvingProteusProperties.t.sol --match-test test_deposit_push_price_over_limit -vvvv
function test_deposit_push_price_over_limit() public { uint256 max_price = 0x5f5e1000000000000000000/2**64; uint256 yBalance = 1e15; uint256 xBalance = 1e15; uint256 totalSupply = 1e15; uint256 specifiedAmount = 1e30; uint256 mintedAmount = DUT.depositGivenInputAmount( yBalance, xBalance, totalSupply, specifiedAmount, SpecifiedToken.X ); uint256 price = (xBalance + specifiedAmount)/(yBalance); assertGt(price, max_price); }
In the above POC, a really large X token is deposited and the price is greater than maximum.
Manual Review
I recommend calling _checkBalances
in function _reserveTokenSpecified
to make sure the price is within [MIN_M, MAX_M) as specified.
Invalid Validation
#0 - c4-pre-sort
2023-08-29T06:07:51Z
0xRobocop marked the issue as duplicate of #268
#1 - c4-pre-sort
2023-08-29T06:07:56Z
0xRobocop marked the issue as sufficient quality report
#2 - c4-judge
2023-09-11T19:20:47Z
JustDravee changed the severity to 3 (High Risk)
#3 - c4-judge
2023-09-11T19:26:17Z
JustDravee marked the issue as satisfactory