Skip to content

Commit

Permalink
fix(evm): Correctly mask leading bits when checking toggle status
Browse files Browse the repository at this point in the history
We were only shifting the trailing bits off the stack but not masking
the leading bits, leading to a situation where incentives could not be
claimed out of order.

This is fixed by and-masking against 1 after shifting the incentive index to
the least significant bit.
  • Loading branch information
topocount committed Sep 30, 2024
1 parent 0a5aaa0 commit a5c7f04
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 1 deletion.
3 changes: 2 additions & 1 deletion packages/evm/contracts/validators/SignerValidator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ library IncentiveBits {
function setOrThrow(IncentiveMap storage bitmap, bytes32 hash, uint256 incentive) internal {
bytes4 invalidSelector = BoostError.IncentiveToBig.selector;
bytes4 claimedSelector = BoostError.IncentiveClaimed.selector;

/// @solidity memory-safe-assembly
assembly {
if gt(incentive, 7) {
Expand All @@ -141,7 +142,7 @@ library IncentiveBits {
// toggle the value that was stored inline on stack with xor
let updatedStorageValue := xor(sload(storageSlot), shl(incentive, 1))
// isolate the toggled bit and see if it's been unset back to zero
let alreadySet := xor(1, shr(incentive, updatedStorageValue))
let alreadySet := xor(1, and(1, shr(incentive, updatedStorageValue)))
if alreadySet {
// revert if the stored value was unset
mstore(0, claimedSelector)
Expand Down
11 changes: 11 additions & 0 deletions packages/evm/test/validators/SignerValidator.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -361,4 +361,15 @@ contract IncentiveBitsTest is Test {
vm.expectRevert(abi.encodeWithSelector(BoostError.IncentiveClaimed.selector, 7));
_used.setOrThrow(fakeHash, 7);
}

function testIncentiveWorksOutofOrder() public {
unchecked {
for (uint256 x = 7; x < 8; x--) {
console.log(x);
_used.setOrThrow(fakeHash, x);
}
}
uint8 map = _used.map[fakeHash];
assertEq(type(uint8).max, map);
}
}

0 comments on commit a5c7f04

Please sign in to comment.