From 423a8087480e8ef8e5ad5440dbbb23583541d177 Mon Sep 17 00:00:00 2001 From: Hadrien Croubois Date: Mon, 27 Feb 2023 11:59:16 +0100 Subject: [PATCH] fix harness --- certora/applyHarness.patch | 349 +++++++++++-------------------------- 1 file changed, 100 insertions(+), 249 deletions(-) diff --git a/certora/applyHarness.patch b/certora/applyHarness.patch index 166366b8b..8895fc597 100644 --- a/certora/applyHarness.patch +++ b/certora/applyHarness.patch @@ -1,7 +1,7 @@ diff -druN access/AccessControl.sol access/AccessControl.sol ---- access/AccessControl.sol 2022-10-31 11:08:30.540461238 +0100 -+++ access/AccessControl.sol 2022-11-04 16:35:52.557358427 +0100 -@@ -93,7 +93,7 @@ +--- access/AccessControl.sol 2023-02-27 10:59:32.652558153 +0100 ++++ access/AccessControl.sol 2023-02-27 11:58:55.064499723 +0100 +@@ -94,7 +94,7 @@ * * _Available since v4.6._ */ @@ -11,8 +11,8 @@ diff -druN access/AccessControl.sol access/AccessControl.sol } diff -druN governance/extensions/GovernorCountingSimple.sol governance/extensions/GovernorCountingSimple.sol ---- governance/extensions/GovernorCountingSimple.sol 2022-10-31 11:08:30.540461238 +0100 -+++ governance/extensions/GovernorCountingSimple.sol 2022-11-04 16:35:52.557358427 +0100 +--- governance/extensions/GovernorCountingSimple.sol 2023-02-27 10:59:32.652558153 +0100 ++++ governance/extensions/GovernorCountingSimple.sol 2023-02-27 11:58:55.064499723 +0100 @@ -27,7 +27,7 @@ mapping(address => bool) hasVoted; } @@ -23,48 +23,52 @@ diff -druN governance/extensions/GovernorCountingSimple.sol governance/extension /** * @dev See {IGovernor-COUNTING_MODE}. diff -druN governance/extensions/GovernorPreventLateQuorum.sol governance/extensions/GovernorPreventLateQuorum.sol ---- governance/extensions/GovernorPreventLateQuorum.sol 2022-08-31 13:44:36.377724869 +0200 -+++ governance/extensions/GovernorPreventLateQuorum.sol 2022-11-04 16:35:52.557358427 +0100 -@@ -21,8 +21,8 @@ +--- governance/extensions/GovernorPreventLateQuorum.sol 2023-02-27 10:59:32.652558153 +0100 ++++ governance/extensions/GovernorPreventLateQuorum.sol 2023-02-27 11:58:55.064499723 +0100 +@@ -20,10 +20,10 @@ + abstract contract GovernorPreventLateQuorum is Governor { using SafeCast for uint256; - using Timers for Timers.BlockNumber; - uint64 private _voteExtension; -- mapping(uint256 => Timers.BlockNumber) private _extendedDeadlines; + uint64 internal _voteExtension; // HARNESS: private -> internal -+ mapping(uint256 => Timers.BlockNumber) internal _extendedDeadlines; // HARNESS: private -> internal + + /// @custom:oz-retyped-from mapping(uint256 => Timers.BlockNumber) +- mapping(uint256 => uint64) private _extendedDeadlines; ++ mapping(uint256 => uint64) internal _extendedDeadlines; // HARNESS: private -> internal /// @dev Emitted when a proposal deadline is pushed back due to reaching quorum late in its voting period. event ProposalExtended(uint256 indexed proposalId, uint64 extendedDeadline); diff -druN governance/extensions/GovernorVotesQuorumFraction.sol governance/extensions/GovernorVotesQuorumFraction.sol ---- governance/extensions/GovernorVotesQuorumFraction.sol 2022-10-31 11:08:30.540461238 +0100 -+++ governance/extensions/GovernorVotesQuorumFraction.sol 2022-11-04 16:35:52.557358427 +0100 -@@ -16,8 +16,8 @@ - abstract contract GovernorVotesQuorumFraction is GovernorVotes { - using Checkpoints for Checkpoints.History; - -- uint256 private _quorumNumerator; // DEPRECATED -- Checkpoints.History private _quorumNumeratorHistory; +--- governance/extensions/GovernorVotesQuorumFraction.sol 2023-02-27 10:59:32.655891529 +0100 ++++ governance/extensions/GovernorVotesQuorumFraction.sol 2023-02-27 11:58:55.064499723 +0100 +@@ -17,10 +17,10 @@ + using SafeCast for *; + using Checkpoints for Checkpoints.Trace224; + +- uint256 private _quorumNumerator; // DEPRECATED in favor of _quorumNumeratorHistory + uint256 internal _quorumNumerator; // DEPRECATED // MUNGED private => internal -+ Checkpoints.History internal _quorumNumeratorHistory; // MUNGED private => internal + + /// @custom:oz-retyped-from Checkpoints.History +- Checkpoints.Trace224 private _quorumNumeratorHistory; ++ Checkpoints.Trace224 internal _quorumNumeratorHistory; // MUNGED private => internal event QuorumNumeratorUpdated(uint256 oldQuorumNumerator, uint256 newQuorumNumerator); diff -druN governance/Governor.sol governance/Governor.sol ---- governance/Governor.sol 2022-11-04 16:13:34.398935222 +0100 -+++ governance/Governor.sol 2022-11-04 16:35:52.560691845 +0100 -@@ -44,7 +44,7 @@ - +--- governance/Governor.sol 2023-02-27 10:59:32.652558153 +0100 ++++ governance/Governor.sol 2023-02-27 11:58:55.064499723 +0100 +@@ -51,7 +51,7 @@ string private _name; + /// @custom:oz-retyped-from mapping(uint256 => Governor.ProposalCore) - mapping(uint256 => ProposalCore) private _proposals; + mapping(uint256 => ProposalCore) internal _proposals; // HARNESS: private -> internal // This queue keeps track of the governor operating on itself. Calls to functions protected by the // {onlyGovernance} modifier needs to be whitelisted in this queue. Whitelisting is set in {_beforeExecute}, diff -druN governance/TimelockController.sol governance/TimelockController.sol ---- governance/TimelockController.sol 2022-11-03 12:06:09.356515929 +0100 -+++ governance/TimelockController.sol 2022-11-04 16:35:52.560691845 +0100 +--- governance/TimelockController.sol 2023-02-27 10:59:32.652558153 +0100 ++++ governance/TimelockController.sol 2023-02-27 11:58:55.067833070 +0100 @@ -28,10 +28,10 @@ bytes32 public constant PROPOSER_ROLE = keccak256("PROPOSER_ROLE"); bytes32 public constant EXECUTOR_ROLE = keccak256("EXECUTOR_ROLE"); @@ -79,8 +83,8 @@ diff -druN governance/TimelockController.sol governance/TimelockController.sol /** * @dev Emitted when a call is scheduled as part of operation `id`. diff -druN governance/utils/Votes.sol governance/utils/Votes.sol ---- governance/utils/Votes.sol 2022-11-03 12:06:09.356515929 +0100 -+++ governance/utils/Votes.sol 2022-11-04 16:35:52.560691845 +0100 +--- governance/utils/Votes.sol 2023-02-27 10:59:32.655891529 +0100 ++++ governance/utils/Votes.sol 2023-02-27 11:58:55.067833070 +0100 @@ -35,7 +35,25 @@ bytes32 private constant _DELEGATION_TYPEHASH = keccak256("Delegation(address delegatee,uint256 nonce,uint256 expiry)"); @@ -105,147 +109,13 @@ diff -druN governance/utils/Votes.sol governance/utils/Votes.sol + } + + mapping(address => address) public _delegation; // HARNESS: private -> public - mapping(address => Checkpoints.History) private _delegateCheckpoints; - Checkpoints.History private _totalCheckpoints; - -@@ -124,7 +142,7 @@ - * - * Emits events {DelegateChanged} and {DelegateVotesChanged}. - */ -- function _delegate(address account, address delegatee) internal virtual { -+ function _delegate(address account, address delegatee) public virtual { // HARNESS: internal -> public - address oldDelegate = delegates(account); - _delegation[account] = delegatee; - -@@ -142,10 +160,10 @@ - uint256 amount - ) internal virtual { - if (from == address(0)) { -- _totalCheckpoints.push(_add, amount); -+ _totalCheckpoints.push(_totalCheckpoints.latest() + amount); // Harnessed to remove function pointers - } - if (to == address(0)) { -- _totalCheckpoints.push(_subtract, amount); -+ _totalCheckpoints.push(_totalCheckpoints.latest() - amount); // Harnessed to remove function pointers - } - _moveDelegateVotes(delegates(from), delegates(to), amount); - } -@@ -160,11 +178,13 @@ - ) private { - if (from != to && amount > 0) { - if (from != address(0)) { -- (uint256 oldValue, uint256 newValue) = _delegateCheckpoints[from].push(_subtract, amount); -+ (uint256 oldValue, uint256 newValue) = _delegateCheckpoints[from].push(_delegateCheckpoints[from].latest() - amount); // Harnessed to remove function pointers -+ _checkpoints[from] = Ckpt({fromBlock: SafeCast.toUint32(block.number), votes: SafeCast.toUint224(newValue)}); // HARNESS - emit DelegateVotesChanged(from, oldValue, newValue); - } - if (to != address(0)) { -- (uint256 oldValue, uint256 newValue) = _delegateCheckpoints[to].push(_add, amount); -+ (uint256 oldValue, uint256 newValue) = _delegateCheckpoints[to].push(_delegateCheckpoints[to].latest() + amount); // Harnessed to remove function pointers -+ _checkpoints[to] = Ckpt({fromBlock: SafeCast.toUint32(block.number), votes: SafeCast.toUint224(newValue)}); // HARNESS - emit DelegateVotesChanged(to, oldValue, newValue); - } - } -@@ -207,5 +227,5 @@ - /** - * @dev Must return the voting units held by an account. - */ -- function _getVotingUnits(address) internal view virtual returns (uint256); -+ function _getVotingUnits(address) public virtual returns (uint256); // HARNESS: internal -> public - } -diff -druN mocks/SafeERC20Helper.sol mocks/SafeERC20Helper.sol ---- mocks/SafeERC20Helper.sol 2022-11-02 19:02:32.463724228 +0100 -+++ mocks/SafeERC20Helper.sol 2022-11-04 16:35:52.560691845 +0100 -@@ -4,7 +4,6 @@ - - import "../utils/Context.sol"; - import "../token/ERC20/IERC20.sol"; --import "../token/ERC20/extensions/draft-ERC20Permit.sol"; - import "../token/ERC20/utils/SafeERC20.sol"; - - contract ERC20ReturnFalseMock is Context { -@@ -106,42 +105,43 @@ - } - } --contract ERC20PermitNoRevertMock is -- ERC20("ERC20PermitNoRevertMock", "ERC20PermitNoRevertMock"), -- ERC20Permit("ERC20PermitNoRevertMock") --{ -- function getChainId() external view returns (uint256) { -- return block.chainid; -- } -+// Harness remove ? -+// contract ERC20PermitNoRevertMock is -+// ERC20("ERC20PermitNoRevertMock", "ERC20PermitNoRevertMock"), -+// ERC20Permit("ERC20PermitNoRevertMock") -+// { -+// function getChainId() external view returns (uint256) { -+// return block.chainid; -+// } - -- function permitThatMayRevert( -- address owner, -- address spender, -- uint256 value, -- uint256 deadline, -- uint8 v, -- bytes32 r, -- bytes32 s -- ) public { -- super.permit(owner, spender, value, deadline, v, r, s); -- } -+// function permitThatMayRevert( -+// address owner, -+// address spender, -+// uint256 value, -+// uint256 deadline, -+// uint8 v, -+// bytes32 r, -+// bytes32 s -+// ) public { -+// super.permit(owner, spender, value, deadline, v, r, s); -+// } - -- function permit( -- address owner, -- address spender, -- uint256 value, -- uint256 deadline, -- uint8 v, -- bytes32 r, -- bytes32 s -- ) public override { -- try this.permitThatMayRevert(owner, spender, value, deadline, v, r, s) { -- // do nothing -- } catch { -- // do nothing -- } -- } --} -+// function permit( -+// address owner, -+// address spender, -+// uint256 value, -+// uint256 deadline, -+// uint8 v, -+// bytes32 r, -+// bytes32 s -+// ) public override { -+// try this.permitThatMayRevert(owner, spender, value, deadline, v, r, s) { -+// // do nothing -+// } catch { -+// // do nothing -+// } -+// } -+// } - - contract SafeERC20Wrapper is Context { - using SafeERC20 for IERC20; + /// @custom:oz-retyped-from mapping(address => Checkpoints.History) + mapping(address => Checkpoints.Trace224) private _delegateCheckpoints; diff -druN proxy/utils/Initializable.sol proxy/utils/Initializable.sol ---- proxy/utils/Initializable.sol 2022-11-03 12:06:09.356515929 +0100 -+++ proxy/utils/Initializable.sol 2022-11-04 16:35:52.560691845 +0100 -@@ -59,12 +59,12 @@ +--- proxy/utils/Initializable.sol 2023-02-27 10:59:32.655891529 +0100 ++++ proxy/utils/Initializable.sol 2023-02-27 11:58:55.067833070 +0100 +@@ -60,12 +60,12 @@ * @dev Indicates that the contract has been initialized. * @custom:oz-retyped-from bool */ @@ -261,8 +131,8 @@ diff -druN proxy/utils/Initializable.sol proxy/utils/Initializable.sol /** * @dev Triggered when the contract has been initialized or reinitialized. diff -druN token/ERC1155/ERC1155.sol token/ERC1155/ERC1155.sol ---- token/ERC1155/ERC1155.sol 2022-10-31 11:08:30.547127922 +0100 -+++ token/ERC1155/ERC1155.sol 2022-11-04 16:35:52.560691845 +0100 +--- token/ERC1155/ERC1155.sol 2023-02-27 10:59:32.655891529 +0100 ++++ token/ERC1155/ERC1155.sol 2023-02-27 11:58:55.067833070 +0100 @@ -21,7 +21,7 @@ using Address for address; @@ -272,7 +142,7 @@ diff -druN token/ERC1155/ERC1155.sol token/ERC1155/ERC1155.sol // Mapping from account to operator approvals mapping(address => mapping(address => bool)) private _operatorApprovals; -@@ -471,7 +471,7 @@ +@@ -451,7 +451,7 @@ uint256 id, uint256 amount, bytes memory data @@ -281,7 +151,7 @@ diff -druN token/ERC1155/ERC1155.sol token/ERC1155/ERC1155.sol if (to.isContract()) { try IERC1155Receiver(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) { if (response != IERC1155Receiver.onERC1155Received.selector) { -@@ -492,7 +492,7 @@ +@@ -472,7 +472,7 @@ uint256[] memory ids, uint256[] memory amounts, bytes memory data @@ -291,9 +161,9 @@ diff -druN token/ERC1155/ERC1155.sol token/ERC1155/ERC1155.sol try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns ( bytes4 response diff -druN token/ERC20/ERC20.sol token/ERC20/ERC20.sol ---- token/ERC20/ERC20.sol 2022-10-31 11:08:30.547127922 +0100 -+++ token/ERC20/ERC20.sol 2022-11-04 16:35:52.560691845 +0100 -@@ -256,7 +256,7 @@ +--- token/ERC20/ERC20.sol 2023-02-27 10:59:32.655891529 +0100 ++++ token/ERC20/ERC20.sol 2023-02-27 11:58:55.067833070 +0100 +@@ -248,7 +248,7 @@ * * - `account` cannot be the zero address. */ @@ -302,7 +172,7 @@ diff -druN token/ERC20/ERC20.sol token/ERC20/ERC20.sol require(account != address(0), "ERC20: mint to the zero address"); _beforeTokenTransfer(address(0), account, amount); -@@ -282,7 +282,7 @@ +@@ -274,7 +274,7 @@ * - `account` cannot be the zero address. * - `account` must have at least `amount` tokens. */ @@ -312,8 +182,8 @@ diff -druN token/ERC20/ERC20.sol token/ERC20/ERC20.sol _beforeTokenTransfer(account, address(0), amount); diff -druN token/ERC20/extensions/ERC20Capped.sol token/ERC20/extensions/ERC20Capped.sol ---- token/ERC20/extensions/ERC20Capped.sol 2022-08-31 13:44:36.381058287 +0200 -+++ token/ERC20/extensions/ERC20Capped.sol 2022-11-04 16:35:52.560691845 +0100 +--- token/ERC20/extensions/ERC20Capped.sol 2023-02-22 15:43:36.624717708 +0100 ++++ token/ERC20/extensions/ERC20Capped.sol 2023-02-27 11:58:55.067833070 +0100 @@ -30,7 +30,7 @@ /** * @dev See {ERC20-_mint}. @@ -324,9 +194,9 @@ diff -druN token/ERC20/extensions/ERC20Capped.sol token/ERC20/extensions/ERC20Ca super._mint(account, amount); } diff -druN token/ERC20/extensions/ERC20FlashMint.sol token/ERC20/extensions/ERC20FlashMint.sol ---- token/ERC20/extensions/ERC20FlashMint.sol 2022-11-03 12:06:09.356515929 +0100 -+++ token/ERC20/extensions/ERC20FlashMint.sol 2022-11-04 16:35:52.560691845 +0100 -@@ -51,9 +51,11 @@ +--- token/ERC20/extensions/ERC20FlashMint.sol 2023-02-27 10:59:32.655891529 +0100 ++++ token/ERC20/extensions/ERC20FlashMint.sol 2023-02-27 11:58:55.067833070 +0100 +@@ -53,9 +53,11 @@ // silence warning about unused variable without the addition of bytecode. token; amount; @@ -340,8 +210,8 @@ diff -druN token/ERC20/extensions/ERC20FlashMint.sol token/ERC20/extensions/ERC2 * @dev Returns the receiver address of the flash fee. By default this * implementation returns the address(0) which means the fee amount will be burnt. diff -druN token/ERC20/extensions/ERC20Votes.sol token/ERC20/extensions/ERC20Votes.sol ---- token/ERC20/extensions/ERC20Votes.sol 2022-11-03 12:06:09.356515929 +0100 -+++ token/ERC20/extensions/ERC20Votes.sol 2022-11-04 16:35:52.560691845 +0100 +--- token/ERC20/extensions/ERC20Votes.sol 2023-02-27 10:59:32.655891529 +0100 ++++ token/ERC20/extensions/ERC20Votes.sol 2023-02-27 11:58:55.067833070 +0100 @@ -33,8 +33,8 @@ bytes32 private constant _DELEGATION_TYPEHASH = keccak256("Delegation(address delegatee,uint256 nonce,uint256 expiry)"); @@ -353,7 +223,7 @@ diff -druN token/ERC20/extensions/ERC20Votes.sol token/ERC20/extensions/ERC20Vot Checkpoint[] private _totalSupplyCheckpoints; /** -@@ -165,27 +165,27 @@ +@@ -186,27 +186,27 @@ /** * @dev Maximum token supply. Defaults to `type(uint224).max` (2^224^ - 1). */ @@ -386,22 +256,21 @@ diff -druN token/ERC20/extensions/ERC20Votes.sol token/ERC20/extensions/ERC20Vot } /** -@@ -208,7 +208,7 @@ +@@ -225,7 +225,7 @@ * - * Emits events {DelegateChanged} and {DelegateVotesChanged}. + * Emits events {IVotes-DelegateChanged} and {IVotes-DelegateVotesChanged}. */ - function _delegate(address delegator, address delegatee) internal virtual { + function _delegate(address delegator, address delegatee) public virtual { // HARNESS: internal -> public address currentDelegate = delegates(delegator); uint256 delegatorBalance = balanceOf(delegator); _delegates[delegator] = delegatee; -@@ -225,36 +225,86 @@ - ) private { +@@ -238,35 +238,60 @@ + function _moveVotingPower(address src, address dst, uint256 amount) private { if (src != dst && amount > 0) { if (src != address(0)) { - (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[src], _subtract, amount); + (uint256 oldWeight, uint256 newWeight) = _writeCheckpointSub(_checkpoints[src], amount); // HARNESS: new version without pointer -+ emit DelegateVotesChanged(src, oldWeight, newWeight); } @@ -414,6 +283,11 @@ diff -druN token/ERC20/extensions/ERC20Votes.sol token/ERC20/extensions/ERC20Vot } - function _writeCheckpoint( +- Checkpoint[] storage ckpts, +- function(uint256, uint256) view returns (uint256) op, +- uint256 delta +- ) private returns (uint256 oldWeight, uint256 newWeight) { ++ // HARNESS: split _writeCheckpoint() to two functions as a workaround for function pointers that cannot be managed by the tool + // function _writeCheckpoint( + // Checkpoint[] storage ckpts, + // function(uint256, uint256) view returns (uint256) op, @@ -421,92 +295,69 @@ diff -druN token/ERC20/extensions/ERC20Votes.sol token/ERC20/extensions/ERC20Vot + // ) private returns (uint256 oldWeight, uint256 newWeight) { + // uint256 pos = ckpts.length; + -+ // Checkpoint memory oldCkpt = pos == 0 ? Checkpoint(0, 0) : _unsafeAccess(ckpts, pos - 1); ++ // unchecked { ++ // Checkpoint memory oldCkpt = pos == 0 ? Checkpoint(0, 0) : _unsafeAccess(ckpts, pos - 1); + -+ // oldWeight = oldCkpt.votes; -+ // newWeight = op(oldWeight, delta); ++ // oldWeight = oldCkpt.votes; ++ // newWeight = op(oldWeight, delta); + -+ // if (pos > 0 && oldCkpt.fromBlock == block.number) { -+ // _unsafeAccess(ckpts, pos - 1).votes = SafeCast.toUint224(newWeight); -+ // } else { -+ // ckpts.push(Checkpoint({fromBlock: SafeCast.toUint32(block.number), votes: SafeCast.toUint224(newWeight)})); ++ // if (pos > 0 && oldCkpt.fromBlock == clock()) { ++ // _unsafeAccess(ckpts, pos - 1).votes = SafeCast.toUint224(newWeight); ++ // } else { ++ // ckpts.push(Checkpoint({fromBlock: SafeCast.toUint32(clock()), votes: SafeCast.toUint224(newWeight)})); ++ // } + // } + // } + -+ // HARNESS: split _writeCheckpoint() to two functions as a workaround for function pointers that cannot be managed by the tool -+ function _writeCheckpointAdd( - Checkpoint[] storage ckpts, -- function(uint256, uint256) view returns (uint256) op, - uint256 delta - ) private returns (uint256 oldWeight, uint256 newWeight) { ++ function _writeCheckpointAdd(Checkpoint[] storage ckpts, uint256 delta) private returns (uint256 oldWeight, uint256 newWeight) { uint256 pos = ckpts.length; + oldWeight = pos == 0 ? 0 : ckpts[pos - 1].votes; + newWeight = _add(oldWeight, delta); -- Checkpoint memory oldCkpt = pos == 0 ? Checkpoint(0, 0) : _unsafeAccess(ckpts, pos - 1); -+ if (pos > 0 && ckpts[pos - 1].fromBlock == block.number) { +- unchecked { +- Checkpoint memory oldCkpt = pos == 0 ? Checkpoint(0, 0) : _unsafeAccess(ckpts, pos - 1); ++ if (pos > 0 && ckpts[pos - 1].fromBlock == clock()) { + ckpts[pos - 1].votes = SafeCast.toUint224(newWeight); + } else { -+ ckpts.push(Checkpoint({fromBlock: SafeCast.toUint32(block.number), votes: SafeCast.toUint224(newWeight)})); ++ ckpts.push(Checkpoint({fromBlock: SafeCast.toUint32(clock()), votes: SafeCast.toUint224(newWeight)})); + } + } -- oldWeight = oldCkpt.votes; -- newWeight = op(oldWeight, delta); -+ function _writeCheckpointSub( -+ Checkpoint[] storage ckpts, -+ uint256 delta -+ ) private returns (uint256 oldWeight, uint256 newWeight) { +- oldWeight = oldCkpt.votes; +- newWeight = op(oldWeight, delta); ++ function _writeCheckpointSub(Checkpoint[] storage ckpts, uint256 delta) private returns (uint256 oldWeight, uint256 newWeight) { + uint256 pos = ckpts.length; + oldWeight = pos == 0 ? 0 : ckpts[pos - 1].votes; + newWeight = _subtract(oldWeight, delta); -- if (pos > 0 && oldCkpt.fromBlock == block.number) { -- _unsafeAccess(ckpts, pos - 1).votes = SafeCast.toUint224(newWeight); -+ if (pos > 0 && ckpts[pos - 1].fromBlock == block.number) { +- if (pos > 0 && oldCkpt.fromBlock == clock()) { +- _unsafeAccess(ckpts, pos - 1).votes = SafeCast.toUint224(newWeight); +- } else { +- ckpts.push(Checkpoint({fromBlock: SafeCast.toUint32(clock()), votes: SafeCast.toUint224(newWeight)})); +- } ++ if (pos > 0 && ckpts[pos - 1].fromBlock == clock()) { + ckpts[pos - 1].votes = SafeCast.toUint224(newWeight); - } else { - ckpts.push(Checkpoint({fromBlock: SafeCast.toUint32(block.number), votes: SafeCast.toUint224(newWeight)})); ++ } else { ++ ckpts.push(Checkpoint({fromBlock: SafeCast.toUint32(clock()), votes: SafeCast.toUint224(newWeight)})); } } -+ // backup of original function -+ // -+ // function _writeCheckpoint( -+ // Checkpoint[] storage ckpts, -+ // function(uint256, uint256) view returns (uint256) op, -+ // uint256 delta -+ // ) private returns (uint256 oldWeight, uint256 newWeight) { -+ // uint256 pos = ckpts.length; -+ // oldWeight = pos == 0 ? 0 : ckpts[pos - 1].votes; -+ // newWeight = op(oldWeight, delta); -+ // -+ // if (pos > 0 && ckpts[pos - 1].fromBlock == block.number) { -+ // ckpts[pos - 1].votes = SafeCast.toUint224(newWeight); -+ // } else { -+ // ckpts.push(Checkpoint({fromBlock: SafeCast.toUint32(block.number), votes: SafeCast.toUint224(newWeight)})); -+ // } -+ // } -+ - function _add(uint256 a, uint256 b) private pure returns (uint256) { - return a + b; - } diff -druN token/ERC20/extensions/ERC20Wrapper.sol token/ERC20/extensions/ERC20Wrapper.sol ---- token/ERC20/extensions/ERC20Wrapper.sol 2022-08-31 13:44:36.381058287 +0200 -+++ token/ERC20/extensions/ERC20Wrapper.sol 2022-11-04 16:35:52.560691845 +0100 -@@ -55,7 +55,7 @@ +--- token/ERC20/extensions/ERC20Wrapper.sol 2023-02-27 10:59:32.655891529 +0100 ++++ token/ERC20/extensions/ERC20Wrapper.sol 2023-02-27 11:58:55.067833070 +0100 +@@ -62,7 +62,7 @@ * @dev Mint wrapped token to cover any underlyingTokens that would have been transferred by mistake. Internal * function that can be exposed with access control if desired. */ - function _recover(address account) internal virtual returns (uint256) { + function _recover(address account) public virtual returns (uint256) { // HARNESS: internal -> public - uint256 value = underlying.balanceOf(address(this)) - totalSupply(); + uint256 value = _underlying.balanceOf(address(this)) - totalSupply(); _mint(account, value); return value; -diff -druN token/ERC721/extensions/draft-ERC721Votes.sol token/ERC721/extensions/draft-ERC721Votes.sol ---- token/ERC721/extensions/draft-ERC721Votes.sol 2022-11-03 12:06:09.356515929 +0100 -+++ token/ERC721/extensions/draft-ERC721Votes.sol 2022-11-04 16:35:52.560691845 +0100 -@@ -49,7 +49,7 @@ +diff -druN token/ERC721/extensions/ERC721Votes.sol token/ERC721/extensions/ERC721Votes.sol +--- token/ERC721/extensions/ERC721Votes.sol 2023-02-27 10:59:32.655891529 +0100 ++++ token/ERC721/extensions/ERC721Votes.sol 2023-02-27 11:58:55.067833070 +0100 +@@ -35,7 +35,7 @@ /** * @dev Returns the balance of `account`. */ @@ -516,8 +367,8 @@ diff -druN token/ERC721/extensions/draft-ERC721Votes.sol token/ERC721/extensions } } diff -druN utils/Address.sol utils/Address.sol ---- utils/Address.sol 2022-11-03 12:06:09.356515929 +0100 -+++ utils/Address.sol 2022-11-04 16:35:52.564025262 +0100 +--- utils/Address.sol 2023-02-27 10:59:32.659224903 +0100 ++++ utils/Address.sol 2023-02-27 11:58:55.067833070 +0100 @@ -197,7 +197,7 @@ bool success, bytes memory returndata, @@ -537,9 +388,9 @@ diff -druN utils/Address.sol utils/Address.sol return returndata; } else { diff -druN utils/Checkpoints.sol utils/Checkpoints.sol ---- utils/Checkpoints.sol 2022-11-02 12:17:36.976298213 +0100 -+++ utils/Checkpoints.sol 2022-11-04 16:35:52.564025262 +0100 -@@ -83,13 +83,13 @@ +--- utils/Checkpoints.sol 2023-02-27 10:59:32.659224903 +0100 ++++ utils/Checkpoints.sol 2023-02-27 11:58:55.071166417 +0100 +@@ -84,13 +84,13 @@ * * Returns previous value and new value. */