Closed sherlock-admin2 closed 9 months ago
1 comment(s) were left on this issue during the judging contest.
takarez commented:
invalid because { I consider this invalid because of the sherlocks rule mentioned in issue 024 and personally i believe when a contract or a function is paused; the devs menas that most of the funcitonalities will paused in case of a secuirity issue}
Tricko
medium
whenNotPaused
modifier inTelcoinDistributor.challengeTransaction()
facilitates the execution of malicious proposals.Summary
Due to the
whenNotPaused
modifier present inTelcoinDistributor.challengeTransaction()
, when theTelcoinDistributor
contract is paused the effective challenge period that is shorter than intended, facilitating the execution of malicious proposals.Vulnerability Detail
The lifecycle of a
TelcoinDistributor
distribution involves several stages. Firstly, any council member can propose a distribution by utilizing theTelcoinDistributor.proposeTransaction()
function. Following this proposal, the distribution remains dormant during the challenge period, which spans from 1 to 7 days (as informed by the sponsor). Finally, the proposed distribution is executed through the invocation ofTelcoinDistributor.executeTransaction()
.Throughout the challenge period, the proposal is in a state where execution is prohibited, opening up the opportunity for other council members to challenge it using the
TelcoinDistributor.challengeTransaction()
function. Notably, the current implementation includes thewhenNotPaused
modifier in thechallengeTransaction()
function, indicating that it is only executable when the contract is in an unpause state.However, it is crucial for
challengeTransaction()
to remain unaffected by pauses. This ensures that a malicious proposal cannot be expedited for execution. During a pause, challenges are not accepted, resulting in an effective challenge period that is shorter than intended. In extreme cases, where the pause duration surpasses the challenge period, a malicious council member can propose and execute without any opportunity from other council members to challenge his proposal.Consider the following scenatio where the attacker (who is also a council member) wants to propose and execute a malicious proposal on a
TelcoinDistributor
with 48h challenge period. Attacker keeps monitoring the mempool, waiting for the owner to callTelcoinDistributor.pause()
pause()
transaction, the attacker tries to frontrun it by proposing his malicious transaction by callingproposeTransaction(...)
.If his frontrun is sucessfull, his proposal would be added to
proposedTransactions
array and the contract will be paused. The attacker continues monitoring the mempool but now for theunpause()
transaction.unpause()
transaction after 50h.TelcoinDistributor.executeTransaction(...)
trying to backrun the owner's transaction, thus executing his malicious proposal as soon as the contract is unpaused, thwarting any attempt to challenge it.This strategy provides the attacker with an advantage. Throughout the pause duration, no challenges to their transaction proposals are possible, diminishing the effective challenge period and facilitating the execution of malicious proposals.
Impact
On the event of a pause, the effective challenge period is smaller than intended. Creating favorable conditions for the execution of malicious proposals.
Code Snippet
https://github.com/sherlock-audit/2024-01-telcoin/blob/0954297f4fefac82d45a79c73f3a4b8eb25f10e9/telcoin-audit/contracts/protocol/core/TelcoinDistributor.sol#L115-L136
Tool used
Manual Review
Recommendation
Consider removing the
whenNotPaused
modifier fromTelcoinDistributor.challengeTransaction()
, thus allowing proposals to be challenged even when contract is paused.Duplicate of #24