Skip to content

Instantly share code, notes, and snippets.

@ItsCuzzo
Last active August 6, 2022 13:23
Show Gist options
  • Save ItsCuzzo/c6f78f8b7e92dc454272fc07fdb9eed1 to your computer and use it in GitHub Desktop.
Save ItsCuzzo/c6f78f8b7e92dc454272fc07fdb9eed1 to your computer and use it in GitHub Desktop.
Implementation of OZ Counters in assembly.
// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.15;
library Counters {
error IntegerUnderflow();
struct Counter {
uint256 value;
}
function current(Counter storage counter) internal view returns (uint256 count) {
assembly {
count := sload(counter.slot)
}
}
function increment(Counter storage counter) internal {
assembly {
sstore(counter.slot, add(sload(counter.slot), 1))
}
}
function decrement(Counter storage counter) internal {
assembly {
let value := sload(counter.slot)
if iszero(value) {
mstore(0x00, 0x6dbd55ba)
revert(0x1c, 0x04)
}
sstore(counter.slot, sub(value, 1))
}
}
function reset(Counter storage counter) internal {
assembly {
sstore(counter.slot, 0)
}
}
}
contract TestCounters {
using Counters for Counters.Counter;
Counters.Counter private _counter;
constructor() {}
/// asm
/// zero to non-zero case: 43327
/// non-zero to non-zero case: 26227
/// regular
/// zero to non-zero case: 43354
/// non-zero to non-zero case: 26254
function add() external {
_counter.increment();
}
/// asm
/// non-zero to non-zero case: 26293
/// non-zero to zero case: 21493
/// revert on 0 - 1 case: 23373
/// regular
/// non-zero to non-zero case: 26327
/// non-zero to zero case: 21527
/// revert on 0 - 1 case: 23677
function sub() external {
_counter.decrement();
}
/// asm
/// 23544
/// regular
/// 23550
function current() external view returns (uint256) {
return _counter.current();
}
/// asm
/// 21487
/// regular
/// 21501
function reset() external {
_counter.reset();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment