Skip to content

Commit

Permalink
T
Browse files Browse the repository at this point in the history
  • Loading branch information
Vectorized committed Oct 14, 2024
1 parent 53253cc commit a519a2a
Showing 1 changed file with 48 additions and 42 deletions.
90 changes: 48 additions & 42 deletions src/tokens/ERC20Votes.sol
Original file line number Diff line number Diff line change
Expand Up @@ -111,48 +111,6 @@ abstract contract ERC20Votes is ERC20 {
return _checkpointUpperLookupRecent(_delegateCheckpointsSlot(account), timepoint);
}

/// @dev Returns the number of checkpoints for `account`.
function checkpointCount(address account) public view virtual returns (uint256 result) {
result = _delegateCheckpointsSlot(account);
/// @solidity memory-safe-assembly
assembly {
result := sload(result)
}
}

/// @dev Returns the voting checkpoint for `account` at index `i`.
function checkpointAt(address account, uint256 i)
public
view
virtual
returns (uint48 checkpointClock, uint256 checkpointValue)
{
uint256 lengthSlot = _delegateCheckpointsSlot(account);
/// @solidity memory-safe-assembly
assembly {
if iszero(lt(i, sload(lengthSlot))) {
mstore(0x00, 0x30607f04) // `ERC5805VoteCheckpointIndexOutOfBounds()`.
revert(0x1c, 0x04)
}
let checkpointSlot := add(i, shl(96, lengthSlot))
let checkpointPacked := sload(checkpointSlot)
checkpointClock := and(0xffffffffffff, checkpointPacked)
checkpointValue := shr(48, checkpointPacked)
if eq(checkpointValue, address()) { checkpointValue := sload(not(checkpointSlot)) }
}
}

/// @dev Returns the latest total voting supply.
function getTotalVotesSupply() public view virtual returns (uint256) {
return _checkpointLatest(_ERC20_VOTES_MASTER_SLOT_SEED);
}

/// @dev Returns the latest amount of total voting units before `timepoint`.
function getPastTotalVotesSupply(uint256 timepoint) public view virtual returns (uint256) {
if (timepoint >= clock()) _revertERC5805FutureLookup();
return _checkpointUpperLookupRecent(_ERC20_VOTES_MASTER_SLOT_SEED, timepoint);
}

/// @dev Returns the current voting delegate of `delegator`.
function delegates(address delegator) public view virtual returns (address result) {
/// @solidity memory-safe-assembly
Expand Down Expand Up @@ -228,6 +186,52 @@ abstract contract ERC20Votes is ERC20 {
_delegate(signer, delegatee);
}

/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* OTHER VOTE PUBLIC VIEW FUNCTIONS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

/// @dev Returns the number of checkpoints for `account`.
function checkpointCount(address account) public view virtual returns (uint256 result) {
result = _delegateCheckpointsSlot(account);
/// @solidity memory-safe-assembly
assembly {
result := sload(result)
}
}

/// @dev Returns the voting checkpoint for `account` at index `i`.
function checkpointAt(address account, uint256 i)
public
view
virtual
returns (uint48 checkpointClock, uint256 checkpointValue)
{
uint256 lengthSlot = _delegateCheckpointsSlot(account);
/// @solidity memory-safe-assembly
assembly {
if iszero(lt(i, sload(lengthSlot))) {
mstore(0x00, 0x30607f04) // `ERC5805VoteCheckpointIndexOutOfBounds()`.
revert(0x1c, 0x04)
}
let checkpointSlot := add(i, shl(96, lengthSlot))
let checkpointPacked := sload(checkpointSlot)
checkpointClock := and(0xffffffffffff, checkpointPacked)
checkpointValue := shr(48, checkpointPacked)
if eq(checkpointValue, address()) { checkpointValue := sload(not(checkpointSlot)) }
}
}

/// @dev Returns the latest total voting supply.
function getTotalVotesSupply() public view virtual returns (uint256) {
return _checkpointLatest(_ERC20_VOTES_MASTER_SLOT_SEED);
}

/// @dev Returns the latest amount of total voting units before `timepoint`.
function getPastTotalVotesSupply(uint256 timepoint) public view virtual returns (uint256) {
if (timepoint >= clock()) _revertERC5805FutureLookup();
return _checkpointUpperLookupRecent(_ERC20_VOTES_MASTER_SLOT_SEED, timepoint);
}

/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* INTERNAL FUNCTIONS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
Expand Down Expand Up @@ -410,6 +414,7 @@ abstract contract ERC20Votes is ERC20 {
let checkpointSlot := shl(96, lengthSlot)
let l := 0 // Low.
let h := n // High.
// Start the binary search nearer to the right to optimize for recent checkpoints.
for {} iszero(lt(n, 6)) {} {
let m := shl(4, lt(0xffff, n))
m := shl(shr(1, or(m, shl(3, lt(0xff, shr(m, n))))), 16)
Expand All @@ -426,6 +431,7 @@ abstract contract ERC20Votes is ERC20 {
h := m
break
}
// Binary search.
for {} lt(l, h) {} {
let m := shr(1, add(l, h)) // Won't overflow in practice.
if iszero(lt(key, and(sload(add(m, checkpointSlot)), 0xffffffffffff))) {
Expand Down

0 comments on commit a519a2a

Please sign in to comment.