Platform: Code4rena
Start Date: 27/11/2023
Pot Size: $36,500 USDC
Total HM: 0
Participants: 22
Period: 8 days
Judge: 0xA5DF
Id: 308
League: ETH
Rank: 6/22
Findings: 1
Award: $814.56
🌟 Selected for report: 0
🚀 Solo Findings: 0
814.5609 USDC - $814.56
Label | Description |
---|---|
L-01 | primitiveOutputAmount() dust outputAmount residue in Curve2PoolAdapter |
L-02 | _erc721Unwrap() Anyone can borrow NFT for free for voting/NFT verification |
L-03 | Use isApprovedForAll permission to restrict forwardedDoInteraction() , posing a significant financial risk to users |
L-04 | approveToken() If the token is USDT, it may not be executable |
In Curve2PoolAdapter.primitiveOutputAmount()
When outputToken
's decimals > 18, it will be converted to 18
, and the truncated dust
will remain in the contract forever, never to be taken out.
If accumulated over time, it may lock up a considerable amount of residual token
in the contract.
It is suggested to add a method for administrators to take away these dust
.
function primitiveOutputAmount( uint256 inputToken, uint256 outputToken, uint256 inputAmount, bytes32 minimumOutputAmount ) internal override returns (uint256 outputAmount) { ... @> outputAmount = _convertDecimals(decimals[outputToken], NORMALIZED_DECIMALS, rawOutputAmount); if (uint256(minimumOutputAmount) > outputAmount) revert SLIPPAGE_LIMIT_EXCEEDED(); if (action == ComputeType.Swap) { emit Swap(inputToken, inputAmount, outputAmount, minimumOutputAmount, primitive, true); } else if (action == ComputeType.Deposit) { emit Deposit(inputToken, inputAmount, outputAmount, minimumOutputAmount, primitive, true); } else { emit Withdraw(outputToken, inputAmount, outputAmount, minimumOutputAmount, primitive, true); } }
Some NFTs will be used for identity verification.
Currently, anyone can borrow NFT (through ERC721Unwarp and then ERC721warp) and perform identity verification, etc., in the custom onERC1155Received()
.
It is suggested to verify the real ownership of NFT when Unwarp.
function _erc721Unwrap(address tokenAddress, uint256 tokenId, address userAddress, uint256 oceanId) private { + require(balanceOf(userAddress,oceanId)==1 ,"Not Your NFT"); IERC721(tokenAddress).safeTransferFrom(address(this), userAddress, tokenId); emit Erc721Unwrap(tokenAddress, tokenId, userAddress, oceanId); }
isApprovedForAll
permission to restrict forwardedDoInteraction()
, posing a significant financial risk to usersCurrently, authorized users (isApprovedForAll()==true) can operate other users' Ocean:ERC1155
through forwardedDoInteraction()
.
But this user can also transfer the token
that this user has not yet transferred into Ocean:ERC1155
through ERC20Wrap
.
This is a very dangerous permission, far greater than just operating Ocean:ERC1155
itself.
For example:
Currently, Alice
has 1000 BTC
, and owns 1 Ocean:ERC1155
, this Ocean:ERC1155
corresponds to 1 BTC.
Alice
executes Ocean:ERC1155.setApprovalForAll(bob)
, mistakenly thinking that bob
can only operate Ocean:ERC1155
, which is worth 1 btc
.bob
can transfer the 1000
BTC
in alice
's wallet into Ocean:ERC1155
through forwardedDoInteraction()->ERC20Wrap
.bob
then transfers away 1001
Ocean:ERC1155
.The price bob
can operate is far greater than 1 btc
.
It is suggested to add other permissions, do not use ERC1155's isApprovedForAll()
. For example, add a new permission: ApprovedOcean
, and note the risk in the document, this can operate any funds in the user's wallet.
Currently, Curve2PoolAdapter._approveToken
is executed using IERC20Metadata.approve()
.
But similar to USDT
, the approve()
method definition does not return.
This leads to the use of IERC20Metadata.approve()
will always revert
.
It is recommended to use oz's safeApprove()
.
#0 - c4-pre-sort
2023-12-10T20:18:23Z
raymondfam marked the issue as sufficient quality report
#1 - 0xA5DF
2023-12-16T11:48:57Z
3L, 1R
Label | Description | Severity |
---|---|---|
L-01 | primitiveOutputAmount() dust outputAmount residue in Curve2PoolAdapter | L |
L-02 | _erc721Unwrap() Anyone can borrow NFT for free for voting/NFT verification | L |
L-03 | Use isApprovedForAll permission to restrict forwardedDoInteraction(), posing a significant financial risk to users | L |
L-04 | approveToken() If the token is USDT, it may not be executable | R |
#2 - c4-judge
2023-12-17T12:12:54Z
0xA5DF marked the issue as grade-c
#3 - c4-judge
2023-12-18T09:10:14Z
0xA5DF marked the issue as grade-a
#4 - c4-judge
2023-12-21T17:24:30Z
0xA5DF marked the issue as grade-b