Platform: Code4rena
Start Date: 21/08/2023
Pot Size: $125,000 USDC
Total HM: 26
Participants: 189
Period: 16 days
Judge: GalloDaSballo
Total Solo HM: 3
Id: 278
League: ETH
Rank: 34/189
Findings: 1
Award: $631.62
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: deadrxsezzz
Also found by: 0xDING99YA, 0xMango, QiuhaoLi, kutugu, pep7siup, said
631.6175 USDC - $631.62
The value obtained from rdpxReserve()
will indirectly determine a rate between the bonding amount and lp amount to remove from the UniV2Amo contract.
As the bonding amount correlates directly with rdpx
and weth
amounts, this setup would halt the protocol from earning income to maintain its peg, whenever isReLPActive
is set to true.
The relevant calculation can be found in the reLP()
function, specifically the uint256 lpToRemove
variable in ReLPContract.sol
ln: 239.
uint256 lpToRemove = (tokenAToRemove * totalLpSupply) / tokenAInfo.tokenALpReserve;
This means that even if the UniV2AMO is sufficiently covered in lp tokens, a low rdpxReserve()
value will calculate for higher lpToRemove numbers, quickly making the bond()
function revert even on considerably small bond amounts.
Seeing how the rdpxReserve()
amount & UniV2Amo lp balance are both very dynamic, scenarios of this happening
are rather likely. Making the reLP
function unreliable when invoked by bond()
.
Creates an unwanted ceiling of how much rdpx
and weth
users can contribute to the protocol via bond()
.
The sponsors Periphery.t.sol contract serves as proof of concept.
https://github.com/code-423n4/2023-08-dopex/blob/eb4d4a201b3a75dd4bddc74a34e9c42c71d0d12f/tests/rdpxV2-core/Periphery.t.sol#L23
The function testReLpContract()
establishes the following states:
lpAmountAmo = 2e218. rdpxReserveContract.rdpxReserve() = 100e18
These values create a bonding amount ceiling of 1.37e18
. In assets this would translate to:
rdpx = 1.6e18; weth = 1.1e18;
This means that transactions attempting to bond more than 1.37e18
will consistently revert unless isReLPActive
is set to false.
Adding 0.37e18 to the bondingAmoung
in line 52 in this test contract to:
rdpxV2Core.bond(1.38 * 1e18, 0, address(this));
will demonstrate this.
To further show just how likely this setup is to revert. If the rdpxReserve()
were to drop to 30 rdpx,
taking the same lp state as above, the rdpx
and weth
seeling for users to spend via bonding becomes:
bondAmount = 7.6e16; // ceiling rdpx = 0.9e18; weth = 0.6e18;
As shown in the POC above, users wanting to contribute larger amounts than this, will have their bond()
calls reverted.
vscode
A straightforward fix is to enclose the reLP function in a try/catch block. In scenarios where the user's amount results in an acceptable lp amount for the UniV2Amo contract, the function will proceed. Otherwise, no lp tokens are removed, but bonding isnt halted either.
Math
#0 - c4-pre-sort
2023-09-10T10:51:15Z
bytes032 marked the issue as low quality report
#1 - c4-judge
2023-10-20T09:01:37Z
GalloDaSballo marked the issue as duplicate of #143
#2 - c4-judge
2023-10-20T09:01:44Z
GalloDaSballo marked the issue as partial-50
#3 - GalloDaSballo
2023-10-20T09:02:06Z
Explanation was unintuitive, took me a while to understand this
I recommend reading the winning reports and simplifying your writing
#4 - c4-judge
2023-10-21T07:57:29Z
GalloDaSballo changed the severity to 3 (High Risk)