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: 31/189
Findings: 2
Award: $650.79
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: LokiThe5th
Also found by: Nikki, __141345__, mahdikarimi, peakbolt, rvierdiiev, wintermute
631.6175 USDC - $631.62
https://github.com/code-423n4/2023-08-dopex/blob/main/contracts/core/RdpxV2Core.sol#L764 https://github.com/code-423n4/2023-08-dopex/blob/main/contracts/core/RdpxV2Core.sol#L772-L774 https://github.com/code-423n4/2023-08-dopex/blob/main/contracts/perp-vault/PerpetualAtlanticVaultLP.sol#L199-L205
A user is able to front-run the call to settle
function in to avoid paying the loss.
settle
is called by Admin which is a public function, When this functions is called the transaction will appear in the mem pool. A user may then call redeem
from LP Vault to withdraw all of their funds.
Manual Review
Consider making the withdrawals a two step process. The first step requests a withdrawal and marks the time. The second request processes the withdrawal but requires a period of time to elapse since the first step.
Other
#0 - bytes032
2023-09-12T12:52:26Z
LQ because of front-running on Arb
#1 - c4-pre-sort
2023-09-12T12:53:05Z
bytes032 marked the issue as low quality report
#2 - bytes032
2023-09-12T12:53:08Z
LQ because of front-running on Arb
#3 - GalloDaSballo
2023-10-09T08:57:45Z
Worth looking again as if the loss is known (predictable) the loss may be avoided
#4 - GalloDaSballo
2023-10-16T08:57:32Z
See #1600
#5 - c4-judge
2023-10-16T08:57:37Z
GalloDaSballo marked the issue as unsatisfactory: Invalid
#6 - c4-judge
2023-10-20T18:54:58Z
GalloDaSballo marked the issue as duplicate of #1584
#7 - c4-judge
2023-10-20T19:06:15Z
GalloDaSballo marked the issue as partial-50
🌟 Selected for report: juancito
Also found by: 0xDING99YA, 0xTiwa, 0xkazim, 0xnev, ABA, ArmedGoose, Aymen0909, Bauchibred, Evo, IceBear, KrisApostolov, MohammedRizwan, Nikki, QiuhaoLi, T1MOH, Toshii, WoolCentaur, Yanchuan, __141345__, asui, bart1e, carrotsmuggler, catellatech, chaduke, codegpt, deadrxsezzz, degensec, dethera, dirk_y, erebus, ether_sky, gjaldon, glcanvas, jasonxiale, josephdara, klau5, kodyvim, ladboy233, lsaudit, minhquanym, parsely, peakbolt, pep7siup, rvierdiiev, said, savi0ur, sces60107, tapir, ubermensch, volodya, zzebra83
19.1724 USDC - $19.17
reserveTokens
in the function removeAssetFromtokenReserves
.
Link:
https://github.com/code-423n4/2023-08-dopex/blob/main/contracts/core/RdpxV2Core.sol#L287Summary:
// remove the asset from the mapping reservesIndex[_assetSymbol] = 0; // add new index for the last element reservesIndex[reserveTokens[reserveTokens.length - 1]] = index; // update the index of reserveAsset with the last element reserveAsset[index] = reserveAsset[reserveAsset.length - 1]; // remove the last element reserveAsset.pop(); reserveTokens.pop();
This would always delete the last symbol of reserveTokens
in the array, irrespective of the _assetSymbol
provided to delete.
POC:
function testPopBugPoc() public { // rdpxV2Core.addAssetTotokenReserves(address(rdpx), "RDPX"); - 1 // rdpxV2Core.addAssetTotokenReserves(address(weth), "WETH"); - 2 // rdpxV2Core.addAssetTotokenReserves(address(dpxETH), "DPXETH"); - 3 assertEq(rdpxV2Core.getReserveAssetLength(), 4); assertEq(rdpxV2Core.getReserveTokensLength(), 3); rdpxV2Core.removeAssetFromtokenReserves("WETH"); uint len = rdpxV2Core.getReserveTokensLength(); string memory tokens_ = rdpxV2Core.reserveTokens(len - 1); assertNotEq(tokens_, "DPXETH"); assertEq(tokens_, "WETH"); }
Recommondations:
function testPopBugPoc() public { rdpxV2Core.addAssetTotokenReserves(address(rdpx), "RDPX"); - 1 rdpxV2Core.addAssetTotokenReserves(address(weth), "WETH"); - 2 rdpxV2Core.addAssetTotokenReserves(address(dpxETH), "DPXETH"); - 3 assertEq(rdpxV2Core.getReserveAssetLength(), 4); assertEq(rdpxV2Core.getReserveTokensLength(), 3); rdpxV2Core.removeAssetFromtokenReserves("WETH"); uint len = rdpxV2Core.getReserveTokensLength(); string memory tokens_ = rdpxV2Core.reserveTokens(len - 1); assertNotEq(tokens_, "DPXETH"); assertEq(tokens_, "WETH"); }
RdpxDecayingBonds
Bond Owner Not Modified on Transfer.
Link:
https://github.com/code-423n4/2023-08-dopex/blob/main/contracts/decaying-bonds/RdpxDecayingBonds.sol#L41Summary: If the bond token is transferred to another user, the Bond Owner in the struct will not get updated.
Link: https://github.com/code-423n4/2023-08-dopex/blob/main/contracts/core/RdpxV2Core.sol#L827 The function doesn't check if the arrays are empty, this could allow any user to mint a nil bond.
Recommendation:
function bondWithDelegate( address _to, uint256[] memory _amounts, uint256[] memory _delegateIds, uint256 rdpxBondId ) public returns (uint256 receiptTokenAmount, uint256[] memory) { _whenNotPaused(); // Validate amount + _validate(_amounts.length != 0, 3); _validate(_amounts.length == _delegateIds.length, 3); ... }
Summary: Some functions behave when tokenId id is 0. This might return unexpected results. https://github.com/code-423n4/2023-08-dopex/blob/main/contracts/core/RdpxV2Core.sol#L630
Summary:
There are no instances of allowances when using safeTransformFrom
.
Summary:
In code, it is stated that the value of slippage tolerance is of 1e8 precision.
To represent 0.5%
, 5e5
is used instead of 5e7
.
/// @notice The slippage tolernce in swaps in 1e8 precision uint256 public slippageTolerance = 5e5; // 0.5%
#0 - c4-pre-sort
2023-09-10T11:41:35Z
bytes032 marked the issue as sufficient quality report
#1 - GalloDaSballo
2023-10-10T11:37:36Z
1 L
2 TODO M
3 L
4 L
5 L
6 Invalid
4L
#2 - c4-judge
2023-10-20T10:21:50Z
GalloDaSballo marked the issue as grade-b