Platform: Code4rena
Start Date: 13/12/2021
Pot Size: $75,000 USDC
Total HM: 11
Participants: 30
Period: 7 days
Judge: leastwood
Total Solo HM: 4
Id: 68
League: ETH
Rank: 17/30
Findings: 4
Award: $739.46
š Selected for report: 1
š Solo Findings: 0
p4st13r4
An attacker can perform a DoS attack by sending a small quantity of outputToken
on SingleTokenJoin
. Affected code is at https://github.com/code-423n4/2021-12-amun/blob/main/contracts/basket/contracts/singleJoinExit/SingleTokenJoin.sol#L134
More details: https://github.com/crytic/slither/wiki/Detector-Documentation#dangerous-strict-equalities
Editor
Possible mitigation: Consider renaming outputAmount
to minOutputAmount
and changing the require to:
require(minOutputAmount >= _joinTokenStruct.outputAmount, "FAILED_OUTPUT_AMOUNT")
#0 - loki-sama
2022-01-03T09:27:10Z
duplicate #81
p4st13r4
Standard ERC20 tokens return a boolean when transfer
method is called. A check should be done to account for ERC20 tokens that are not compliant to the standard.
Relevant lines:
Editor
Check transfer
return value, or use Openzeppelinā safeTransfer
#0 - loki-sama
2022-01-04T10:30:33Z
duplicate #232
#1 - 0xleastwood
2022-01-22T04:09:08Z
Duplicate of #192
p4st13r4
Contracts in the folder basket/contracts/singleJoinExit
makes use of unsafe address.transfer()
method.
The use of such function could have unintended outcomes on the eth being sent to the receiver. Funds can potentially be lost if:
The latter situation may occur in the instance of gas cost changes. The impact would mean that any contracts receiving funds would potentially be unable to retrieve funds
Affected lines are here:
Editor
Consider using address.call{value: v}("")
and checking the return value or Openzeppelin Address
library instead
#0 - loki-sama
2021-12-29T11:46:52Z
Duplicate #231
#1 - 0xleastwood
2022-01-23T03:27:32Z
Duplicate of #175
š Selected for report: p4st13r4
p4st13r4
If a rebalance is done in more than one transaction, locking the basket at each transaction can be avoided.
Editor
(a) ImplementĀ lock()
Ā method inĀ RebalanceManager.sol
,Ā RebalanceManagerV2.sol
,Ā RebalanceManagerV3.sol
Ā as:
function lock() external onlyRebalanceManager { basket.singleCall( address(basket), abi.encodeWithSelector(basket.setLock.selector, _block), 0 ); }
Effectively makingĀ lockBasketData
Ā not needed.RebalanceManager.sol
,Ā RebalanceManagerV2.sol
Ā will need a new constructor argumentĀ uint256 _lockTime
Ā and a new state variableĀ uint256 public lockTime
.
(b) InĀ RebalanceManager.sol
,Ā RebalanceManagerV2.sol
,Ā RebalanceManagerV3.sol
Ā remove the lineĀ lockBasketData(block.number + 30)
Ā at the beginning ofĀ rebalance
Ā method.
(c) OnĀ rebalance
Ā method first line inĀ RebalanceManager.sol
,Ā RebalanceManagerV2.sol
Ā addĀ require(basket.getLock(), "REQUIRE_LOCK")
Ā (as in contracts/basket/contracts/callManagers/RebalanceManagerV3.sol)
When performing a rebalance:
(d) CallĀ RebalanceManager.lock()
.
(e) Perform the rebalance using theĀ rebalance()
Ā method.