Open code423n4 opened 2 years ago
The issue outlined by the warden is relevant but users won't need to execute arbitrary calls cause potential rewards given out to ticket holders will be handled by our TWABRewards contract.
This contract retrieves users TWAB (Time-Weighted Average Balance) for a given period of time and calculate the amount of rewards they are eligible to.
Users can then claimRewards
on behalf of others. So delegatees will be able to claim their rewards and delegators could claim on their behalf.
https://github.com/pooltogether/v4-periphery/blob/348d2bf7cfcf5750bad4aae63b8ade5a2a45f188/contracts/TwabRewards.sol#L410 https://github.com/pooltogether/v4-periphery/blob/348d2bf7cfcf5750bad4aae63b8ade5a2a45f188/contracts/interfaces/ITwabRewards.sol#L94
For more informations about how the TWAB works, here is some documentation:
Also, by restricting calls to the transfer
and delegate` methods on the ticket, we limit the attack surface and any attack vector we may not have thought about.
For the reasons above, I've acknowledged the issue but we won't implement the proposed solution
I don't really see a case where _delegateCall()
or _transferCall()
will need to have some ETH attached with it. They are solely dealing with the Ticket ERC20 token and updating delegation data. Considering the fact that rewards are handled by a separate contract, I think its fair to downgrade this to 1 (Low Risk)
.
Since this issue was downgraded to a QA level, and the warden did not submit a separate QA report, we've renamed this one to "QA report" for consistency.
The original title, for the record, was "[WP-M1] delegator and/or representative should be allowed for arbitrary code execution besides restricted operations during unlocked period."
Lines of code
https://github.com/pooltogether/v4-twab-delegator/blob/21bb53b2ea54a248bbd1d3170dbadd3a0c83d874/contracts/Delegation.sol#L39-L46
Vulnerability details
Delegation
is a contract deployed dedicated to holding theticket
tokens for thedelegator
and they can then bedelegate
to adelegatee
.On the
Delegation
contract, there is a method namedexecuteCalls()
designed for "Executes calls on behalf of this contract" which allows arbitrary code execution for the owner.However, we found that the owner of
Delegation
will always beTWABDelegator
, and theTWABDelegator
will only useDelegation.sol#executeCalls()
to call one particular address: theticket
address, and for only two methods:transfer()
anddelegate()
.Furthermore, even though in
Delegation.sol#executeCalls()
,calls[i].value
is used, the function is not being marked aspayable
, that makes it hard for calls that requires eth payments.https://github.com/pooltogether/v4-twab-delegator/blob/21bb53b2ea54a248bbd1d3170dbadd3a0c83d874/contracts/Delegation.sol#L39-L46
While the
ticket
is being delegated throughTWABDelegator
, they won't be able to retrieve the tickets back until thelockUntil
, without the ability to make arbitrary code execution, thedelegator
may miss some of the potential benefits as a holder of theticket
tokens, for example, an airdrop to all holders of theticket
tokens, or an NFT made mintable only for certain ticket holders.Recommendation
Consider adding a new method on
TWABDelegator
:And also, consider making
Delegation.sol#executeCalls()
apayable
method.