Closed code423n4 closed 1 year ago
https://github.com/code-423n4/2023-03-mute/blob/4d8b13add2907b17ac14627cfa04e0c3cc9a2bed/contracts/bonds/MuteBond.sol#L119
The Mutebond contract might stop working after the owner decreased maxPayout by a malicious frontrunner.
Mutebond
maxPayout
setMaxPayout() can be used to reset maxPayout.
setMaxPayout()
function setMaxPayout(uint _payout) external { require(msg.sender == customTreasury.owner()); maxPayout = _payout; emit MaxPayoutChanged(_payout); }
And in deposit(), epoch is increased only when terms[epoch].payoutTotal == maxPayout.
deposit()
terms[epoch].payoutTotal == maxPayout
File: MuteBond.sol 193: if(terms[epoch].payoutTotal == maxPayout){ 194: terms.push(BondTerms(0,0,0)); 195: epochStart = block.timestamp; 196: epoch++; 197: }
So when the owner is going to decrease maxPayout for some reason, the below scenario would be possible by a malicious user.
epoch = 1, maxPayout = 1000, terms[epoch].payoutTotal = 500
_payout = 800
value = 400
terms[epoch].payoutTotal = 900
function maxDeposit() public view returns (uint) { return maxPayout.sub(terms[epoch].payoutTotal); }
As a result, the contract doesn't work until the owner increases back maxPayout.
It would be more serious when it takes certain time to execute the admin functions as it should be approved by DAO.
Manual Review
setMaxPayout() should check if the updated maxPayout isn't less than the current epoch's payoutTotal.
payoutTotal
function setMaxPayout(uint _payout) external { require(msg.sender == customTreasury.owner()); require(_payout >= terms[epoch].payoutTotal); //++++++++++++++++++++ maxPayout = _payout; emit MaxPayoutChanged(_payout); }
Picodes marked the issue as primary issue
mattt21 marked the issue as sponsor confirmed
Picodes marked the issue as satisfactory
Picodes marked issue #14 as primary and marked this issue as a duplicate of 14
Lines of code
https://github.com/code-423n4/2023-03-mute/blob/4d8b13add2907b17ac14627cfa04e0c3cc9a2bed/contracts/bonds/MuteBond.sol#L119
Vulnerability details
Impact
The
Mutebond
contract might stop working after the owner decreasedmaxPayout
by a malicious frontrunner.Proof of Concept
setMaxPayout()
can be used to resetmaxPayout
.And in
deposit()
, epoch is increased only whenterms[epoch].payoutTotal == maxPayout
.So when the owner is going to decrease
maxPayout
for some reason, the below scenario would be possible by a malicious user.epoch = 1, maxPayout = 1000, terms[epoch].payoutTotal = 500
maxPayout
to 800 for some reason and calledsetMaxPayout()
with_payout = 800
.deposit()
withvalue = 400
.deposit()
is called,terms[epoch].payoutTotal = 900
andmaxPayout
will be 800.deposit()
will revert because maxDeposit() reverts due to uint underflow.As a result, the contract doesn't work until the owner increases back
maxPayout
.It would be more serious when it takes certain time to execute the admin functions as it should be approved by DAO.
Tools Used
Manual Review
Recommended Mitigation Steps
setMaxPayout()
should check if the updatedmaxPayout
isn't less than the current epoch'spayoutTotal
.