diff --git a/certora/applyHarness.patch b/certora/applyHarness.patch index 9dbbc8e43..833d550dc 100644 --- a/certora/applyHarness.patch +++ b/certora/applyHarness.patch @@ -1,6 +1,6 @@ diff -ruN access/AccessControl.sol access/AccessControl.sol --- access/AccessControl.sol 2022-05-25 15:36:58.849363940 -0400 -+++ access/AccessControl.sol 2022-05-25 15:37:51.040083904 -0400 ++++ access/AccessControl.sol 2022-05-25 16:04:57.725255723 -0400 @@ -93,7 +93,7 @@ * * _Available since v4.6._ @@ -12,7 +12,7 @@ diff -ruN access/AccessControl.sol access/AccessControl.sol diff -ruN governance/extensions/GovernorPreventLateQuorum.sol governance/extensions/GovernorPreventLateQuorum.sol --- governance/extensions/GovernorPreventLateQuorum.sol 2022-05-25 15:36:58.849363940 -0400 -+++ governance/extensions/GovernorPreventLateQuorum.sol 2022-05-25 15:37:51.044083806 -0400 ++++ governance/extensions/GovernorPreventLateQuorum.sol 2022-05-25 16:04:57.725255723 -0400 @@ -21,8 +21,8 @@ using SafeCast for uint256; using Timers for Timers.BlockNumber; @@ -26,7 +26,7 @@ diff -ruN governance/extensions/GovernorPreventLateQuorum.sol governance/extensi event ProposalExtended(uint256 indexed proposalId, uint64 extendedDeadline); diff -ruN governance/Governor.sol governance/Governor.sol --- governance/Governor.sol 2022-05-25 15:36:58.849363940 -0400 -+++ governance/Governor.sol 2022-05-25 15:37:51.040083904 -0400 ++++ governance/Governor.sol 2022-05-25 16:04:57.725255723 -0400 @@ -44,7 +44,7 @@ string private _name; @@ -36,609 +36,9 @@ diff -ruN governance/Governor.sol governance/Governor.sol // 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 -ruN governance/Governor.sol.orig governance/Governor.sol.orig ---- governance/Governor.sol.orig 1969-12-31 19:00:00.000000000 -0500 -+++ governance/Governor.sol.orig 2022-05-25 15:37:51.036084000 -0400 -@@ -0,0 +1,596 @@ -+// SPDX-License-Identifier: MIT -+// OpenZeppelin Contracts (last updated v4.6.0) (governance/Governor.sol) -+ -+pragma solidity ^0.8.0; -+ -+import "../token/ERC721/IERC721Receiver.sol"; -+import "../token/ERC1155/IERC1155Receiver.sol"; -+import "../utils/cryptography/ECDSA.sol"; -+import "../utils/cryptography/draft-EIP712.sol"; -+import "../utils/introspection/ERC165.sol"; -+import "../utils/math/SafeCast.sol"; -+import "../utils/structs/DoubleEndedQueue.sol"; -+import "../utils/Address.sol"; -+import "../utils/Context.sol"; -+import "../utils/Timers.sol"; -+import "./IGovernor.sol"; -+ -+/** -+ * @dev Core of the governance system, designed to be extended though various modules. -+ * -+ * This contract is abstract and requires several function to be implemented in various modules: -+ * -+ * - A counting module must implement {quorum}, {_quorumReached}, {_voteSucceeded} and {_countVote} -+ * - A voting module must implement {_getVotes} -+ * - Additionanly, the {votingPeriod} must also be implemented -+ * -+ * _Available since v4.3._ -+ */ -+abstract contract Governor is Context, ERC165, EIP712, IGovernor, IERC721Receiver, IERC1155Receiver { -+ using DoubleEndedQueue for DoubleEndedQueue.Bytes32Deque; -+ using SafeCast for uint256; -+ using Timers for Timers.BlockNumber; -+ -+ bytes32 public constant BALLOT_TYPEHASH = keccak256("Ballot(uint256 proposalId,uint8 support)"); -+ bytes32 public constant EXTENDED_BALLOT_TYPEHASH = -+ keccak256("ExtendedBallot(uint256 proposalId,uint8 support,string reason,bytes params)"); -+ -+ struct ProposalCore { -+ Timers.BlockNumber voteStart; -+ Timers.BlockNumber voteEnd; -+ bool executed; -+ bool canceled; -+ } -+ -+ string private _name; -+ -+ mapping(uint256 => ProposalCore) private _proposals; -+ -+ // 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}, -+ // consumed by the {onlyGovernance} modifier and eventually reset in {_afterExecute}. This ensures that the -+ // execution of {onlyGovernance} protected calls can only be achieved through successful proposals. -+ DoubleEndedQueue.Bytes32Deque private _governanceCall; -+ -+ /** -+ * @dev Restricts a function so it can only be executed through governance proposals. For example, governance -+ * parameter setters in {GovernorSettings} are protected using this modifier. -+ * -+ * The governance executing address may be different from the Governor's own address, for example it could be a -+ * timelock. This can be customized by modules by overriding {_executor}. The executor is only able to invoke these -+ * functions during the execution of the governor's {execute} function, and not under any other circumstances. Thus, -+ * for example, additional timelock proposers are not able to change governance parameters without going through the -+ * governance protocol (since v4.6). -+ */ -+ modifier onlyGovernance() { -+ require(_msgSender() == _executor(), "Governor: onlyGovernance"); -+ if (_executor() != address(this)) { -+ bytes32 msgDataHash = keccak256(_msgData()); -+ // loop until popping the expected operation - throw if deque is empty (operation not authorized) -+ while (_governanceCall.popFront() != msgDataHash) {} -+ } -+ _; -+ } -+ -+ /** -+ * @dev Sets the value for {name} and {version} -+ */ -+ constructor(string memory name_) EIP712(name_, version()) { -+ _name = name_; -+ } -+ -+ /** -+ * @dev Function to receive ETH that will be handled by the governor (disabled if executor is a third party contract) -+ */ -+ receive() external payable virtual { -+ require(_executor() == address(this)); -+ } -+ -+ /** -+ * @dev See {IERC165-supportsInterface}. -+ */ -+ function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC165) returns (bool) { -+ // In addition to the current interfaceId, also support previous version of the interfaceId that did not -+ // include the castVoteWithReasonAndParams() function as standard -+ return -+ interfaceId == -+ (type(IGovernor).interfaceId ^ -+ this.castVoteWithReasonAndParams.selector ^ -+ this.castVoteWithReasonAndParamsBySig.selector ^ -+ this.getVotesWithParams.selector) || -+ interfaceId == type(IGovernor).interfaceId || -+ interfaceId == type(IERC1155Receiver).interfaceId || -+ super.supportsInterface(interfaceId); -+ } -+ -+ /** -+ * @dev See {IGovernor-name}. -+ */ -+ function name() public view virtual override returns (string memory) { -+ return _name; -+ } -+ -+ /** -+ * @dev See {IGovernor-version}. -+ */ -+ function version() public view virtual override returns (string memory) { -+ return "1"; -+ } -+ -+ /** -+ * @dev See {IGovernor-hashProposal}. -+ * -+ * The proposal id is produced by hashing the RLC encoded `targets` array, the `values` array, the `calldatas` array -+ * and the descriptionHash (bytes32 which itself is the keccak256 hash of the description string). This proposal id -+ * can be produced from the proposal data which is part of the {ProposalCreated} event. It can even be computed in -+ * advance, before the proposal is submitted. -+ * -+ * Note that the chainId and the governor address are not part of the proposal id computation. Consequently, the -+ * same proposal (with same operation and same description) will have the same id if submitted on multiple governors -+ * across multiple networks. This also means that in order to execute the same operation twice (on the same -+ * governor) the proposer will have to change the description in order to avoid proposal id conflicts. -+ */ -+ function hashProposal( -+ address[] memory targets, -+ uint256[] memory values, -+ bytes[] memory calldatas, -+ bytes32 descriptionHash -+ ) public pure virtual override returns (uint256) { -+ return uint256(keccak256(abi.encode(targets, values, calldatas, descriptionHash))); -+ } -+ -+ /** -+ * @dev See {IGovernor-state}. -+ */ -+ function state(uint256 proposalId) public view virtual override returns (ProposalState) { -+ ProposalCore storage proposal = _proposals[proposalId]; -+ -+ if (proposal.executed) { -+ return ProposalState.Executed; -+ } -+ -+ if (proposal.canceled) { -+ return ProposalState.Canceled; -+ } -+ -+ uint256 snapshot = proposalSnapshot(proposalId); -+ -+ if (snapshot == 0) { -+ revert("Governor: unknown proposal id"); -+ } -+ -+ if (snapshot >= block.number) { -+ return ProposalState.Pending; -+ } -+ -+ uint256 deadline = proposalDeadline(proposalId); -+ -+ if (deadline >= block.number) { -+ return ProposalState.Active; -+ } -+ -+ if (_quorumReached(proposalId) && _voteSucceeded(proposalId)) { -+ return ProposalState.Succeeded; -+ } else { -+ return ProposalState.Defeated; -+ } -+ } -+ -+ /** -+ * @dev See {IGovernor-proposalSnapshot}. -+ */ -+ function proposalSnapshot(uint256 proposalId) public view virtual override returns (uint256) { -+ return _proposals[proposalId].voteStart.getDeadline(); -+ } -+ -+ /** -+ * @dev See {IGovernor-proposalDeadline}. -+ */ -+ function proposalDeadline(uint256 proposalId) public view virtual override returns (uint256) { -+ return _proposals[proposalId].voteEnd.getDeadline(); -+ } -+ -+ /** -+ * @dev Part of the Governor Bravo's interface: _"The number of votes required in order for a voter to become a proposer"_. -+ */ -+ function proposalThreshold() public view virtual returns (uint256) { -+ return 0; -+ } -+ -+ /** -+ * @dev Amount of votes already cast passes the threshold limit. -+ */ -+ function _quorumReached(uint256 proposalId) internal view virtual returns (bool); -+ -+ /** -+ * @dev Is the proposal successful or not. -+ */ -+ function _voteSucceeded(uint256 proposalId) internal view virtual returns (bool); -+ -+ /** -+ * @dev Get the voting weight of `account` at a specific `blockNumber`, for a vote as described by `params`. -+ */ -+ function _getVotes( -+ address account, -+ uint256 blockNumber, -+ bytes memory params -+ ) internal view virtual returns (uint256); -+ -+ /** -+ * @dev Register a vote for `proposalId` by `account` with a given `support`, voting `weight` and voting `params`. -+ * -+ * Note: Support is generic and can represent various things depending on the voting system used. -+ */ -+ function _countVote( -+ uint256 proposalId, -+ address account, -+ uint8 support, -+ uint256 weight, -+ bytes memory params -+ ) internal virtual; -+ -+ /** -+ * @dev Default additional encoded parameters used by castVote methods that don't include them -+ * -+ * Note: Should be overridden by specific implementations to use an appropriate value, the -+ * meaning of the additional params, in the context of that implementation -+ */ -+ function _defaultParams() internal view virtual returns (bytes memory) { -+ return ""; -+ } -+ -+ /** -+ * @dev See {IGovernor-propose}. -+ */ -+ function propose( -+ address[] memory targets, -+ uint256[] memory values, -+ bytes[] memory calldatas, -+ string memory description -+ ) public virtual override returns (uint256) { -+ require( -+ getVotes(_msgSender(), block.number - 1) >= proposalThreshold(), -+ "Governor: proposer votes below proposal threshold" -+ ); -+ -+ uint256 proposalId = hashProposal(targets, values, calldatas, keccak256(bytes(description))); -+ -+ require(targets.length == values.length, "Governor: invalid proposal length"); -+ require(targets.length == calldatas.length, "Governor: invalid proposal length"); -+ require(targets.length > 0, "Governor: empty proposal"); -+ -+ ProposalCore storage proposal = _proposals[proposalId]; -+ require(proposal.voteStart.isUnset(), "Governor: proposal already exists"); -+ -+ uint64 snapshot = block.number.toUint64() + votingDelay().toUint64(); -+ uint64 deadline = snapshot + votingPeriod().toUint64(); -+ -+ proposal.voteStart.setDeadline(snapshot); -+ proposal.voteEnd.setDeadline(deadline); -+ -+ emit ProposalCreated( -+ proposalId, -+ _msgSender(), -+ targets, -+ values, -+ new string[](targets.length), -+ calldatas, -+ snapshot, -+ deadline, -+ description -+ ); -+ -+ return proposalId; -+ } -+ -+ /** -+ * @dev See {IGovernor-execute}. -+ */ -+ function execute( -+ address[] memory targets, -+ uint256[] memory values, -+ bytes[] memory calldatas, -+ bytes32 descriptionHash -+ ) public payable virtual override returns (uint256) { -+ uint256 proposalId = hashProposal(targets, values, calldatas, descriptionHash); -+ -+ ProposalState status = state(proposalId); -+ require( -+ status == ProposalState.Succeeded || status == ProposalState.Queued, -+ "Governor: proposal not successful" -+ ); -+ _proposals[proposalId].executed = true; -+ -+ emit ProposalExecuted(proposalId); -+ -+ _beforeExecute(proposalId, targets, values, calldatas, descriptionHash); -+ _execute(proposalId, targets, values, calldatas, descriptionHash); -+ _afterExecute(proposalId, targets, values, calldatas, descriptionHash); -+ -+ return proposalId; -+ } -+ -+ /** -+ * @dev Internal execution mechanism. Can be overridden to implement different execution mechanism -+ */ -+ function _execute( -+ uint256, /* proposalId */ -+ address[] memory targets, -+ uint256[] memory values, -+ bytes[] memory calldatas, -+ bytes32 /*descriptionHash*/ -+ ) internal virtual { -+ string memory errorMessage = "Governor: call reverted without message"; -+ for (uint256 i = 0; i < targets.length; ++i) { -+ (bool success, bytes memory returndata) = targets[i].call{value: values[i]}(calldatas[i]); -+ Address.verifyCallResult(success, returndata, errorMessage); -+ } -+ } -+ -+ /** -+ * @dev Hook before execution is triggered. -+ */ -+ function _beforeExecute( -+ uint256, /* proposalId */ -+ address[] memory targets, -+ uint256[] memory, /* values */ -+ bytes[] memory calldatas, -+ bytes32 /*descriptionHash*/ -+ ) internal virtual { -+ if (_executor() != address(this)) { -+ for (uint256 i = 0; i < targets.length; ++i) { -+ if (targets[i] == address(this)) { -+ _governanceCall.pushBack(keccak256(calldatas[i])); -+ } -+ } -+ } -+ } -+ -+ /** -+ * @dev Hook after execution is triggered. -+ */ -+ function _afterExecute( -+ uint256, /* proposalId */ -+ address[] memory, /* targets */ -+ uint256[] memory, /* values */ -+ bytes[] memory, /* calldatas */ -+ bytes32 /*descriptionHash*/ -+ ) internal virtual { -+ if (_executor() != address(this)) { -+ if (!_governanceCall.empty()) { -+ _governanceCall.clear(); -+ } -+ } -+ } -+ -+ /** -+ * @dev Internal cancel mechanism: locks up the proposal timer, preventing it from being re-submitted. Marks it as -+ * canceled to allow distinguishing it from executed proposals. -+ * -+ * Emits a {IGovernor-ProposalCanceled} event. -+ */ -+ function _cancel( -+ address[] memory targets, -+ uint256[] memory values, -+ bytes[] memory calldatas, -+ bytes32 descriptionHash -+ ) internal virtual returns (uint256) { -+ uint256 proposalId = hashProposal(targets, values, calldatas, descriptionHash); -+ ProposalState status = state(proposalId); -+ -+ require( -+ status != ProposalState.Canceled && status != ProposalState.Expired && status != ProposalState.Executed, -+ "Governor: proposal not active" -+ ); -+ _proposals[proposalId].canceled = true; -+ -+ emit ProposalCanceled(proposalId); -+ -+ return proposalId; -+ } -+ -+ /** -+ * @dev See {IGovernor-getVotes}. -+ */ -+ function getVotes(address account, uint256 blockNumber) public view virtual override returns (uint256) { -+ return _getVotes(account, blockNumber, _defaultParams()); -+ } -+ -+ /** -+ * @dev See {IGovernor-getVotesWithParams}. -+ */ -+ function getVotesWithParams( -+ address account, -+ uint256 blockNumber, -+ bytes memory params -+ ) public view virtual override returns (uint256) { -+ return _getVotes(account, blockNumber, params); -+ } -+ -+ /** -+ * @dev See {IGovernor-castVote}. -+ */ -+ function castVote(uint256 proposalId, uint8 support) public virtual override returns (uint256) { -+ address voter = _msgSender(); -+ return _castVote(proposalId, voter, support, ""); -+ } -+ -+ /** -+ * @dev See {IGovernor-castVoteWithReason}. -+ */ -+ function castVoteWithReason( -+ uint256 proposalId, -+ uint8 support, -+ string calldata reason -+ ) public virtual override returns (uint256) { -+ address voter = _msgSender(); -+ return _castVote(proposalId, voter, support, reason); -+ } -+ -+ /** -+ * @dev See {IGovernor-castVoteWithReasonAndParams}. -+ */ -+ function castVoteWithReasonAndParams( -+ uint256 proposalId, -+ uint8 support, -+ string calldata reason, -+ bytes memory params -+ ) public virtual override returns (uint256) { -+ address voter = _msgSender(); -+ return _castVote(proposalId, voter, support, reason, params); -+ } -+ -+ /** -+ * @dev See {IGovernor-castVoteBySig}. -+ */ -+ function castVoteBySig( -+ uint256 proposalId, -+ uint8 support, -+ uint8 v, -+ bytes32 r, -+ bytes32 s -+ ) public virtual override returns (uint256) { -+ address voter = ECDSA.recover( -+ _hashTypedDataV4(keccak256(abi.encode(BALLOT_TYPEHASH, proposalId, support))), -+ v, -+ r, -+ s -+ ); -+ return _castVote(proposalId, voter, support, ""); -+ } -+ -+ /** -+ * @dev See {IGovernor-castVoteWithReasonAndParamsBySig}. -+ */ -+ function castVoteWithReasonAndParamsBySig( -+ uint256 proposalId, -+ uint8 support, -+ string calldata reason, -+ bytes memory params, -+ uint8 v, -+ bytes32 r, -+ bytes32 s -+ ) public virtual override returns (uint256) { -+ address voter = ECDSA.recover( -+ _hashTypedDataV4( -+ keccak256( -+ abi.encode( -+ EXTENDED_BALLOT_TYPEHASH, -+ proposalId, -+ support, -+ keccak256(bytes(reason)), -+ keccak256(params) -+ ) -+ ) -+ ), -+ v, -+ r, -+ s -+ ); -+ -+ return _castVote(proposalId, voter, support, reason, params); -+ } -+ -+ /** -+ * @dev Internal vote casting mechanism: Check that the vote is pending, that it has not been cast yet, retrieve -+ * voting weight using {IGovernor-getVotes} and call the {_countVote} internal function. Uses the _defaultParams(). -+ * -+ * Emits a {IGovernor-VoteCast} event. -+ */ -+ function _castVote( -+ uint256 proposalId, -+ address account, -+ uint8 support, -+ string memory reason -+ ) internal virtual returns (uint256) { -+ return _castVote(proposalId, account, support, reason, _defaultParams()); -+ } -+ -+ /** -+ * @dev Internal vote casting mechanism: Check that the vote is pending, that it has not been cast yet, retrieve -+ * voting weight using {IGovernor-getVotes} and call the {_countVote} internal function. -+ * -+ * Emits a {IGovernor-VoteCast} event. -+ */ -+ function _castVote( -+ uint256 proposalId, -+ address account, -+ uint8 support, -+ string memory reason, -+ bytes memory params -+ ) internal virtual returns (uint256) { -+ ProposalCore storage proposal = _proposals[proposalId]; -+ require(state(proposalId) == ProposalState.Active, "Governor: vote not currently active"); -+ -+ uint256 weight = _getVotes(account, proposal.voteStart.getDeadline(), params); -+ _countVote(proposalId, account, support, weight, params); -+ -+ if (params.length == 0) { -+ emit VoteCast(account, proposalId, support, weight, reason); -+ } else { -+ emit VoteCastWithParams(account, proposalId, support, weight, reason, params); -+ } -+ -+ return weight; -+ } -+ -+ /** -+ * @dev Relays a transaction or function call to an arbitrary target. In cases where the governance executor -+ * is some contract other than the governor itself, like when using a timelock, this function can be invoked -+ * in a governance proposal to recover tokens or Ether that was sent to the governor contract by mistake. -+ * Note that if the executor is simply the governor itself, use of `relay` is redundant. -+ */ -+ function relay( -+ address target, -+ uint256 value, -+ bytes calldata data -+ ) external virtual onlyGovernance { -+ Address.functionCallWithValue(target, data, value); -+ } -+ -+ /** -+ * @dev Address through which the governor executes action. Will be overloaded by module that execute actions -+ * through another contract such as a timelock. -+ */ -+ function _executor() internal view virtual returns (address) { -+ return address(this); -+ } -+ -+ /** -+ * @dev See {IERC721Receiver-onERC721Received}. -+ */ -+ function onERC721Received( -+ address, -+ address, -+ uint256, -+ bytes memory -+ ) public virtual override returns (bytes4) { -+ return this.onERC721Received.selector; -+ } -+ -+ /** -+ * @dev See {IERC1155Receiver-onERC1155Received}. -+ */ -+ function onERC1155Received( -+ address, -+ address, -+ uint256, -+ uint256, -+ bytes memory -+ ) public virtual override returns (bytes4) { -+ return this.onERC1155Received.selector; -+ } -+ -+ /** -+ * @dev See {IERC1155Receiver-onERC1155BatchReceived}. -+ */ -+ function onERC1155BatchReceived( -+ address, -+ address, -+ uint256[] memory, -+ uint256[] memory, -+ bytes memory -+ ) public virtual override returns (bytes4) { -+ return this.onERC1155BatchReceived.selector; -+ } -+} diff -ruN governance/TimelockController.sol governance/TimelockController.sol --- governance/TimelockController.sol 2022-05-25 15:36:58.849363940 -0400 -+++ governance/TimelockController.sol 2022-05-25 15:52:28.134311018 -0400 ++++ governance/TimelockController.sol 2022-05-25 16:04:57.725255723 -0400 @@ -28,10 +28,10 @@ bytes32 public constant PROPOSER_ROLE = keccak256("PROPOSER_ROLE"); bytes32 public constant EXECUTOR_ROLE = keccak256("EXECUTOR_ROLE"); @@ -652,430 +52,9 @@ diff -ruN governance/TimelockController.sol governance/TimelockController.sol /** * @dev Emitted when a call is scheduled as part of operation `id`. -diff -ruN governance/TimelockController.sol.orig governance/TimelockController.sol.orig ---- governance/TimelockController.sol.orig 1969-12-31 19:00:00.000000000 -0500 -+++ governance/TimelockController.sol.orig 2022-05-25 15:37:51.036084000 -0400 -@@ -0,0 +1,417 @@ -+// SPDX-License-Identifier: MIT -+// OpenZeppelin Contracts (last updated v4.6.0) (governance/TimelockController.sol) -+ -+pragma solidity ^0.8.0; -+ -+import "../access/AccessControl.sol"; -+import "../token/ERC721/IERC721Receiver.sol"; -+import "../token/ERC1155/IERC1155Receiver.sol"; -+import "../utils/Address.sol"; -+ -+/** -+ * @dev Contract module which acts as a timelocked controller. When set as the -+ * owner of an `Ownable` smart contract, it enforces a timelock on all -+ * `onlyOwner` maintenance operations. This gives time for users of the -+ * controlled contract to exit before a potentially dangerous maintenance -+ * operation is applied. -+ * -+ * By default, this contract is self administered, meaning administration tasks -+ * have to go through the timelock process. The proposer (resp executor) role -+ * is in charge of proposing (resp executing) operations. A common use case is -+ * to position this {TimelockController} as the owner of a smart contract, with -+ * a multisig or a DAO as the sole proposer. -+ * -+ * _Available since v3.3._ -+ */ -+contract TimelockController is AccessControl, IERC721Receiver, IERC1155Receiver { -+ bytes32 public constant TIMELOCK_ADMIN_ROLE = keccak256("TIMELOCK_ADMIN_ROLE"); -+ bytes32 public constant PROPOSER_ROLE = keccak256("PROPOSER_ROLE"); -+ bytes32 public constant EXECUTOR_ROLE = keccak256("EXECUTOR_ROLE"); -+ bytes32 public constant CANCELLER_ROLE = keccak256("CANCELLER_ROLE"); -+ uint256 internal constant _DONE_TIMESTAMP = uint256(1); -+ -+ mapping(bytes32 => uint256) private _timestamps; -+ uint256 private _minDelay; -+ -+ /** -+ * @dev Emitted when a call is scheduled as part of operation `id`. -+ */ -+ event CallScheduled( -+ bytes32 indexed id, -+ uint256 indexed index, -+ address target, -+ uint256 value, -+ bytes data, -+ bytes32 predecessor, -+ uint256 delay -+ ); -+ -+ /** -+ * @dev Emitted when a call is performed as part of operation `id`. -+ */ -+ event CallExecuted(bytes32 indexed id, uint256 indexed index, address target, uint256 value, bytes data); -+ -+ /** -+ * @dev Emitted when operation `id` is cancelled. -+ */ -+ event Cancelled(bytes32 indexed id); -+ -+ /** -+ * @dev Emitted when the minimum delay for future operations is modified. -+ */ -+ event MinDelayChange(uint256 oldDuration, uint256 newDuration); -+ -+ /** -+ * @dev Initializes the contract with a given `minDelay`, and a list of -+ * initial proposers and executors. The proposers receive both the -+ * proposer and the canceller role (for backward compatibility). The -+ * executors receive the executor role. -+ * -+ * NOTE: At construction, both the deployer and the timelock itself are -+ * administrators. This helps further configuration of the timelock by the -+ * deployer. After configuration is done, it is recommended that the -+ * deployer renounces its admin position and relies on timelocked -+ * operations to perform future maintenance. -+ */ -+ constructor( -+ uint256 minDelay, -+ address[] memory proposers, -+ address[] memory executors -+ ) { -+ _setRoleAdmin(TIMELOCK_ADMIN_ROLE, TIMELOCK_ADMIN_ROLE); -+ _setRoleAdmin(PROPOSER_ROLE, TIMELOCK_ADMIN_ROLE); -+ _setRoleAdmin(EXECUTOR_ROLE, TIMELOCK_ADMIN_ROLE); -+ _setRoleAdmin(CANCELLER_ROLE, TIMELOCK_ADMIN_ROLE); -+ -+ // deployer + self administration -+ _setupRole(TIMELOCK_ADMIN_ROLE, _msgSender()); -+ _setupRole(TIMELOCK_ADMIN_ROLE, address(this)); -+ -+ // register proposers and cancellers -+ for (uint256 i = 0; i < proposers.length; ++i) { -+ _setupRole(PROPOSER_ROLE, proposers[i]); -+ _setupRole(CANCELLER_ROLE, proposers[i]); -+ } -+ -+ // register executors -+ for (uint256 i = 0; i < executors.length; ++i) { -+ _setupRole(EXECUTOR_ROLE, executors[i]); -+ } -+ -+ _minDelay = minDelay; -+ emit MinDelayChange(0, minDelay); -+ } -+ -+ /** -+ * @dev Modifier to make a function callable only by a certain role. In -+ * addition to checking the sender's role, `address(0)` 's role is also -+ * considered. Granting a role to `address(0)` is equivalent to enabling -+ * this role for everyone. -+ */ -+ modifier onlyRoleOrOpenRole(bytes32 role) { -+ if (!hasRole(role, address(0))) { -+ _checkRole(role, _msgSender()); -+ } -+ _; -+ } -+ -+ /** -+ * @dev Contract might receive/hold ETH as part of the maintenance process. -+ */ -+ receive() external payable {} -+ -+ /** -+ * @dev See {IERC165-supportsInterface}. -+ */ -+ function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, AccessControl) returns (bool) { -+ return interfaceId == type(IERC1155Receiver).interfaceId || super.supportsInterface(interfaceId); -+ } -+ -+ /** -+ * @dev Returns whether an id correspond to a registered operation. This -+ * includes both Pending, Ready and Done operations. -+ */ -+ function isOperation(bytes32 id) public view virtual returns (bool registered) { -+ return getTimestamp(id) > 0; -+ } -+ -+ /** -+ * @dev Returns whether an operation is pending or not. -+ */ -+ function isOperationPending(bytes32 id) public view virtual returns (bool pending) { -+ return getTimestamp(id) > _DONE_TIMESTAMP; -+ } -+ -+ /** -+ * @dev Returns whether an operation is ready or not. -+ */ -+ function isOperationReady(bytes32 id) public view virtual returns (bool ready) { -+ uint256 timestamp = getTimestamp(id); -+ return timestamp > _DONE_TIMESTAMP && timestamp <= block.timestamp; -+ } -+ -+ /** -+ * @dev Returns whether an operation is done or not. -+ */ -+ function isOperationDone(bytes32 id) public view virtual returns (bool done) { -+ return getTimestamp(id) == _DONE_TIMESTAMP; -+ } -+ -+ /** -+ * @dev Returns the timestamp at with an operation becomes ready (0 for -+ * unset operations, 1 for done operations). -+ */ -+ function getTimestamp(bytes32 id) public view virtual returns (uint256 timestamp) { -+ return _timestamps[id]; -+ } -+ -+ /** -+ * @dev Returns the minimum delay for an operation to become valid. -+ * -+ * This value can be changed by executing an operation that calls `updateDelay`. -+ */ -+ function getMinDelay() public view virtual returns (uint256 duration) { -+ return _minDelay; -+ } -+ -+ /** -+ * @dev Returns the identifier of an operation containing a single -+ * transaction. -+ */ -+ function hashOperation( -+ address target, -+ uint256 value, -+ bytes calldata data, -+ bytes32 predecessor, -+ bytes32 salt -+ ) public pure virtual returns (bytes32 hash) { -+ return keccak256(abi.encode(target, value, data, predecessor, salt)); -+ } -+ -+ /** -+ * @dev Returns the identifier of an operation containing a batch of -+ * transactions. -+ */ -+ function hashOperationBatch( -+ address[] calldata targets, -+ uint256[] calldata values, -+ bytes[] calldata payloads, -+ bytes32 predecessor, -+ bytes32 salt -+ ) public pure virtual returns (bytes32 hash) { -+ return keccak256(abi.encode(targets, values, payloads, predecessor, salt)); -+ } -+ -+ /** -+ * @dev Schedule an operation containing a single transaction. -+ * -+ * Emits a {CallScheduled} event. -+ * -+ * Requirements: -+ * -+ * - the caller must have the 'proposer' role. -+ */ -+ function schedule( -+ address target, -+ uint256 value, -+ bytes calldata data, -+ bytes32 predecessor, -+ bytes32 salt, -+ uint256 delay -+ ) public virtual onlyRole(PROPOSER_ROLE) { -+ bytes32 id = hashOperation(target, value, data, predecessor, salt); -+ _schedule(id, delay); -+ emit CallScheduled(id, 0, target, value, data, predecessor, delay); -+ } -+ -+ /** -+ * @dev Schedule an operation containing a batch of transactions. -+ * -+ * Emits one {CallScheduled} event per transaction in the batch. -+ * -+ * Requirements: -+ * -+ * - the caller must have the 'proposer' role. -+ */ -+ function scheduleBatch( -+ address[] calldata targets, -+ uint256[] calldata values, -+ bytes[] calldata payloads, -+ bytes32 predecessor, -+ bytes32 salt, -+ uint256 delay -+ ) public virtual onlyRole(PROPOSER_ROLE) { -+ require(targets.length == values.length, "TimelockController: length mismatch"); -+ require(targets.length == payloads.length, "TimelockController: length mismatch"); -+ -+ bytes32 id = hashOperationBatch(targets, values, payloads, predecessor, salt); -+ _schedule(id, delay); -+ for (uint256 i = 0; i < targets.length; ++i) { -+ emit CallScheduled(id, i, targets[i], values[i], payloads[i], predecessor, delay); -+ } -+ } -+ -+ /** -+ * @dev Schedule an operation that is to becomes valid after a given delay. -+ */ -+ function _schedule(bytes32 id, uint256 delay) private { -+ require(!isOperation(id), "TimelockController: operation already scheduled"); -+ require(delay >= getMinDelay(), "TimelockController: insufficient delay"); -+ _timestamps[id] = block.timestamp + delay; -+ } -+ -+ /** -+ * @dev Cancel an operation. -+ * -+ * Requirements: -+ * -+ * - the caller must have the 'canceller' role. -+ */ -+ function cancel(bytes32 id) public virtual onlyRole(CANCELLER_ROLE) { -+ require(isOperationPending(id), "TimelockController: operation cannot be cancelled"); -+ delete _timestamps[id]; -+ -+ emit Cancelled(id); -+ } -+ -+ /** -+ * @dev Execute an (ready) operation containing a single transaction. -+ * -+ * Emits a {CallExecuted} event. -+ * -+ * Requirements: -+ * -+ * - the caller must have the 'executor' role. -+ */ -+ // This function can reenter, but it doesn't pose a risk because _afterCall checks that the proposal is pending, -+ // thus any modifications to the operation during reentrancy should be caught. -+ // slither-disable-next-line reentrancy-eth -+ function execute( -+ address target, -+ uint256 value, -+ bytes calldata payload, -+ bytes32 predecessor, -+ bytes32 salt -+ ) public payable virtual onlyRoleOrOpenRole(EXECUTOR_ROLE) { -+ bytes32 id = hashOperation(target, value, payload, predecessor, salt); -+ -+ _beforeCall(id, predecessor); -+ _execute(target, value, payload); -+ emit CallExecuted(id, 0, target, value, payload); -+ _afterCall(id); -+ } -+ -+ /** -+ * @dev Execute an (ready) operation containing a batch of transactions. -+ * -+ * Emits one {CallExecuted} event per transaction in the batch. -+ * -+ * Requirements: -+ * -+ * - the caller must have the 'executor' role. -+ */ -+ function executeBatch( -+ address[] calldata targets, -+ uint256[] calldata values, -+ bytes[] calldata payloads, -+ bytes32 predecessor, -+ bytes32 salt -+ ) public payable virtual onlyRoleOrOpenRole(EXECUTOR_ROLE) { -+ require(targets.length == values.length, "TimelockController: length mismatch"); -+ require(targets.length == payloads.length, "TimelockController: length mismatch"); -+ -+ bytes32 id = hashOperationBatch(targets, values, payloads, predecessor, salt); -+ -+ _beforeCall(id, predecessor); -+ for (uint256 i = 0; i < targets.length; ++i) { -+ address target = targets[i]; -+ uint256 value = values[i]; -+ bytes calldata payload = payloads[i]; -+ _execute(target, value, payload); -+ emit CallExecuted(id, i, target, value, payload); -+ } -+ _afterCall(id); -+ } -+ -+ /** -+ * @dev Execute an operation's call. -+ */ -+ function _execute( -+ address target, -+ uint256 value, -+ bytes calldata data -+ ) internal virtual { -+ (bool success, ) = target.call{value: value}(data); -+ require(success, "TimelockController: underlying transaction reverted"); -+ } -+ -+ /** -+ * @dev Checks before execution of an operation's calls. -+ */ -+ function _beforeCall(bytes32 id, bytes32 predecessor) private view { -+ require(isOperationReady(id), "TimelockController: operation is not ready"); -+ require(predecessor == bytes32(0) || isOperationDone(predecessor), "TimelockController: missing dependency"); -+ } -+ -+ /** -+ * @dev Checks after execution of an operation's calls. -+ */ -+ function _afterCall(bytes32 id) private { -+ require(isOperationReady(id), "TimelockController: operation is not ready"); -+ _timestamps[id] = _DONE_TIMESTAMP; -+ } -+ -+ /** -+ * @dev Changes the minimum timelock duration for future operations. -+ * -+ * Emits a {MinDelayChange} event. -+ * -+ * Requirements: -+ * -+ * - the caller must be the timelock itself. This can only be achieved by scheduling and later executing -+ * an operation where the timelock is the target and the data is the ABI-encoded call to this function. -+ */ -+ function updateDelay(uint256 newDelay) external virtual { -+ require(msg.sender == address(this), "TimelockController: caller must be timelock"); -+ emit MinDelayChange(_minDelay, newDelay); -+ _minDelay = newDelay; -+ } -+ -+ /** -+ * @dev See {IERC721Receiver-onERC721Received}. -+ */ -+ function onERC721Received( -+ address, -+ address, -+ uint256, -+ bytes memory -+ ) public virtual override returns (bytes4) { -+ return this.onERC721Received.selector; -+ } -+ -+ /** -+ * @dev See {IERC1155Receiver-onERC1155Received}. -+ */ -+ function onERC1155Received( -+ address, -+ address, -+ uint256, -+ uint256, -+ bytes memory -+ ) public virtual override returns (bytes4) { -+ return this.onERC1155Received.selector; -+ } -+ -+ /** -+ * @dev See {IERC1155Receiver-onERC1155BatchReceived}. -+ */ -+ function onERC1155BatchReceived( -+ address, -+ address, -+ uint256[] memory, -+ uint256[] memory, -+ bytes memory -+ ) public virtual override returns (bytes4) { -+ return this.onERC1155BatchReceived.selector; -+ } -+} diff -ruN governance/utils/Votes.sol governance/utils/Votes.sol --- governance/utils/Votes.sol 2022-05-25 15:36:58.849363940 -0400 -+++ governance/utils/Votes.sol 2022-05-25 15:49:40.913370387 -0400 ++++ governance/utils/Votes.sol 2022-05-25 16:04:57.725255723 -0400 @@ -35,7 +35,25 @@ bytes32 private constant _DELEGATION_TYPEHASH = keccak256("Delegation(address delegatee,uint256 nonce,uint256 expiry)"); @@ -1148,224 +127,9 @@ diff -ruN governance/utils/Votes.sol governance/utils/Votes.sol - function _getVotingUnits(address) internal view virtual returns (uint256); + function _getVotingUnits(address) public virtual returns (uint256); // HARNESS: internal -> public } -diff -ruN governance/utils/Votes.sol.orig governance/utils/Votes.sol.orig ---- governance/utils/Votes.sol.orig 1969-12-31 19:00:00.000000000 -0500 -+++ governance/utils/Votes.sol.orig 2022-05-25 15:37:51.036084000 -0400 -@@ -0,0 +1,211 @@ -+// SPDX-License-Identifier: MIT -+// OpenZeppelin Contracts (last updated v4.6.0) (governance/utils/Votes.sol) -+pragma solidity ^0.8.0; -+ -+import "../../utils/Context.sol"; -+import "../../utils/Counters.sol"; -+import "../../utils/Checkpoints.sol"; -+import "../../utils/cryptography/draft-EIP712.sol"; -+import "./IVotes.sol"; -+ -+/** -+ * @dev This is a base abstract contract that tracks voting units, which are a measure of voting power that can be -+ * transferred, and provides a system of vote delegation, where an account can delegate its voting units to a sort of -+ * "representative" that will pool delegated voting units from different accounts and can then use it to vote in -+ * decisions. In fact, voting units _must_ be delegated in order to count as actual votes, and an account has to -+ * delegate those votes to itself if it wishes to participate in decisions and does not have a trusted representative. -+ * -+ * This contract is often combined with a token contract such that voting units correspond to token units. For an -+ * example, see {ERC721Votes}. -+ * -+ * The full history of delegate votes is tracked on-chain so that governance protocols can consider votes as distributed -+ * at a particular block number to protect against flash loans and double voting. The opt-in delegate system makes the -+ * cost of this history tracking optional. -+ * -+ * When using this module the derived contract must implement {_getVotingUnits} (for example, make it return -+ * {ERC721-balanceOf}), and can use {_transferVotingUnits} to track a change in the distribution of those units (in the -+ * previous example, it would be included in {ERC721-_beforeTokenTransfer}). -+ * -+ * _Available since v4.5._ -+ */ -+abstract contract Votes is IVotes, Context, EIP712 { -+ using Checkpoints for Checkpoints.History; -+ using Counters for Counters.Counter; -+ -+ bytes32 private constant _DELEGATION_TYPEHASH = -+ keccak256("Delegation(address delegatee,uint256 nonce,uint256 expiry)"); -+ -+ mapping(address => address) private _delegation; -+ mapping(address => Checkpoints.History) private _delegateCheckpoints; -+ Checkpoints.History private _totalCheckpoints; -+ -+ mapping(address => Counters.Counter) private _nonces; -+ -+ /** -+ * @dev Returns the current amount of votes that `account` has. -+ */ -+ function getVotes(address account) public view virtual override returns (uint256) { -+ return _delegateCheckpoints[account].latest(); -+ } -+ -+ /** -+ * @dev Returns the amount of votes that `account` had at the end of a past block (`blockNumber`). -+ * -+ * Requirements: -+ * -+ * - `blockNumber` must have been already mined -+ */ -+ function getPastVotes(address account, uint256 blockNumber) public view virtual override returns (uint256) { -+ return _delegateCheckpoints[account].getAtBlock(blockNumber); -+ } -+ -+ /** -+ * @dev Returns the total supply of votes available at the end of a past block (`blockNumber`). -+ * -+ * NOTE: This value is the sum of all available votes, which is not necessarily the sum of all delegated votes. -+ * Votes that have not been delegated are still part of total supply, even though they would not participate in a -+ * vote. -+ * -+ * Requirements: -+ * -+ * - `blockNumber` must have been already mined -+ */ -+ function getPastTotalSupply(uint256 blockNumber) public view virtual override returns (uint256) { -+ require(blockNumber < block.number, "Votes: block not yet mined"); -+ return _totalCheckpoints.getAtBlock(blockNumber); -+ } -+ -+ /** -+ * @dev Returns the current total supply of votes. -+ */ -+ function _getTotalSupply() internal view virtual returns (uint256) { -+ return _totalCheckpoints.latest(); -+ } -+ -+ /** -+ * @dev Returns the delegate that `account` has chosen. -+ */ -+ function delegates(address account) public view virtual override returns (address) { -+ return _delegation[account]; -+ } -+ -+ /** -+ * @dev Delegates votes from the sender to `delegatee`. -+ */ -+ function delegate(address delegatee) public virtual override { -+ address account = _msgSender(); -+ _delegate(account, delegatee); -+ } -+ -+ /** -+ * @dev Delegates votes from signer to `delegatee`. -+ */ -+ function delegateBySig( -+ address delegatee, -+ uint256 nonce, -+ uint256 expiry, -+ uint8 v, -+ bytes32 r, -+ bytes32 s -+ ) public virtual override { -+ require(block.timestamp <= expiry, "Votes: signature expired"); -+ address signer = ECDSA.recover( -+ _hashTypedDataV4(keccak256(abi.encode(_DELEGATION_TYPEHASH, delegatee, nonce, expiry))), -+ v, -+ r, -+ s -+ ); -+ require(nonce == _useNonce(signer), "Votes: invalid nonce"); -+ _delegate(signer, delegatee); -+ } -+ -+ /** -+ * @dev Delegate all of `account`'s voting units to `delegatee`. -+ * -+ * Emits events {DelegateChanged} and {DelegateVotesChanged}. -+ */ -+ function _delegate(address account, address delegatee) internal virtual { -+ address oldDelegate = delegates(account); -+ _delegation[account] = delegatee; -+ -+ emit DelegateChanged(account, oldDelegate, delegatee); -+ _moveDelegateVotes(oldDelegate, delegatee, _getVotingUnits(account)); -+ } -+ -+ /** -+ * @dev Transfers, mints, or burns voting units. To register a mint, `from` should be zero. To register a burn, `to` -+ * should be zero. Total supply of voting units will be adjusted with mints and burns. -+ */ -+ function _transferVotingUnits( -+ address from, -+ address to, -+ uint256 amount -+ ) internal virtual { -+ if (from == address(0)) { -+ _totalCheckpoints.push(_add, amount); -+ } -+ if (to == address(0)) { -+ _totalCheckpoints.push(_subtract, amount); -+ } -+ _moveDelegateVotes(delegates(from), delegates(to), amount); -+ } -+ -+ /** -+ * @dev Moves delegated votes from one delegate to another. -+ */ -+ function _moveDelegateVotes( -+ address from, -+ address to, -+ uint256 amount -+ ) private { -+ if (from != to && amount > 0) { -+ if (from != address(0)) { -+ (uint256 oldValue, uint256 newValue) = _delegateCheckpoints[from].push(_subtract, amount); -+ emit DelegateVotesChanged(from, oldValue, newValue); -+ } -+ if (to != address(0)) { -+ (uint256 oldValue, uint256 newValue) = _delegateCheckpoints[to].push(_add, amount); -+ emit DelegateVotesChanged(to, oldValue, newValue); -+ } -+ } -+ } -+ -+ function _add(uint256 a, uint256 b) private pure returns (uint256) { -+ return a + b; -+ } -+ -+ function _subtract(uint256 a, uint256 b) private pure returns (uint256) { -+ return a - b; -+ } -+ -+ /** -+ * @dev Consumes a nonce. -+ * -+ * Returns the current value and increments nonce. -+ */ -+ function _useNonce(address owner) internal virtual returns (uint256 current) { -+ Counters.Counter storage nonce = _nonces[owner]; -+ current = nonce.current(); -+ nonce.increment(); -+ } -+ -+ /** -+ * @dev Returns an address nonce. -+ */ -+ function nonces(address owner) public view virtual returns (uint256) { -+ return _nonces[owner].current(); -+ } -+ -+ /** -+ * @dev Returns the contract's {EIP712} domain separator. -+ */ -+ // solhint-disable-next-line func-name-mixedcase -+ function DOMAIN_SEPARATOR() external view returns (bytes32) { -+ return _domainSeparatorV4(); -+ } -+ -+ /** -+ * @dev Must return the voting units held by an account. -+ */ -+ function _getVotingUnits(address) internal view virtual returns (uint256); -+} diff -ruN token/ERC1155/ERC1155.sol token/ERC1155/ERC1155.sol --- token/ERC1155/ERC1155.sol 2022-05-25 15:36:58.853363841 -0400 -+++ token/ERC1155/ERC1155.sol 2022-05-25 15:37:51.044083806 -0400 ++++ token/ERC1155/ERC1155.sol 2022-05-25 16:04:57.725255723 -0400 @@ -268,7 +268,7 @@ uint256 id, uint256 amount, @@ -1420,530 +184,9 @@ diff -ruN token/ERC1155/ERC1155.sol token/ERC1155/ERC1155.sol if (to.isContract()) { try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns ( bytes4 response -diff -ruN token/ERC1155/ERC1155.sol.orig token/ERC1155/ERC1155.sol.orig ---- token/ERC1155/ERC1155.sol.orig 1969-12-31 19:00:00.000000000 -0500 -+++ token/ERC1155/ERC1155.sol.orig 2022-05-25 15:37:51.036084000 -0400 -@@ -0,0 +1,517 @@ -+// SPDX-License-Identifier: MIT -+// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC1155/ERC1155.sol) -+ -+pragma solidity ^0.8.0; -+ -+import "./IERC1155.sol"; -+import "./IERC1155Receiver.sol"; -+import "./extensions/IERC1155MetadataURI.sol"; -+import "../../utils/Address.sol"; -+import "../../utils/Context.sol"; -+import "../../utils/introspection/ERC165.sol"; -+ -+/** -+ * @dev Implementation of the basic standard multi-token. -+ * See https://eips.ethereum.org/EIPS/eip-1155 -+ * Originally based on code by Enjin: https://github.com/enjin/erc-1155 -+ * -+ * _Available since v3.1._ -+ */ -+contract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI { -+ using Address for address; -+ -+ // Mapping from token ID to account balances -+ mapping(uint256 => mapping(address => uint256)) private _balances; -+ -+ // Mapping from account to operator approvals -+ mapping(address => mapping(address => bool)) private _operatorApprovals; -+ -+ // Used as the URI for all token types by relying on ID substitution, e.g. https://token-cdn-domain/{id}.json -+ string private _uri; -+ -+ /** -+ * @dev See {_setURI}. -+ */ -+ constructor(string memory uri_) { -+ _setURI(uri_); -+ } -+ -+ /** -+ * @dev See {IERC165-supportsInterface}. -+ */ -+ function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) { -+ return -+ interfaceId == type(IERC1155).interfaceId || -+ interfaceId == type(IERC1155MetadataURI).interfaceId || -+ super.supportsInterface(interfaceId); -+ } -+ -+ /** -+ * @dev See {IERC1155MetadataURI-uri}. -+ * -+ * This implementation returns the same URI for *all* token types. It relies -+ * on the token type ID substitution mechanism -+ * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP]. -+ * -+ * Clients calling this function must replace the `\{id\}` substring with the -+ * actual token type ID. -+ */ -+ function uri(uint256) public view virtual override returns (string memory) { -+ return _uri; -+ } -+ -+ /** -+ * @dev See {IERC1155-balanceOf}. -+ * -+ * Requirements: -+ * -+ * - `account` cannot be the zero address. -+ */ -+ function balanceOf(address account, uint256 id) public view virtual override returns (uint256) { -+ require(account != address(0), "ERC1155: address zero is not a valid owner"); -+ return _balances[id][account]; -+ } -+ -+ /** -+ * @dev See {IERC1155-balanceOfBatch}. -+ * -+ * Requirements: -+ * -+ * - `accounts` and `ids` must have the same length. -+ */ -+ function balanceOfBatch(address[] memory accounts, uint256[] memory ids) -+ public -+ view -+ virtual -+ override -+ returns (uint256[] memory) -+ { -+ require(accounts.length == ids.length, "ERC1155: accounts and ids length mismatch"); -+ -+ uint256[] memory batchBalances = new uint256[](accounts.length); -+ -+ for (uint256 i = 0; i < accounts.length; ++i) { -+ batchBalances[i] = balanceOf(accounts[i], ids[i]); -+ } -+ -+ return batchBalances; -+ } -+ -+ /** -+ * @dev See {IERC1155-setApprovalForAll}. -+ */ -+ function setApprovalForAll(address operator, bool approved) public virtual override { -+ _setApprovalForAll(_msgSender(), operator, approved); -+ } -+ -+ /** -+ * @dev See {IERC1155-isApprovedForAll}. -+ */ -+ function isApprovedForAll(address account, address operator) public view virtual override returns (bool) { -+ return _operatorApprovals[account][operator]; -+ } -+ -+ /** -+ * @dev See {IERC1155-safeTransferFrom}. -+ */ -+ function safeTransferFrom( -+ address from, -+ address to, -+ uint256 id, -+ uint256 amount, -+ bytes memory data -+ ) public virtual override { -+ require( -+ from == _msgSender() || isApprovedForAll(from, _msgSender()), -+ "ERC1155: caller is not owner nor approved" -+ ); -+ _safeTransferFrom(from, to, id, amount, data); -+ } -+ -+ /** -+ * @dev See {IERC1155-safeBatchTransferFrom}. -+ */ -+ function safeBatchTransferFrom( -+ address from, -+ address to, -+ uint256[] memory ids, -+ uint256[] memory amounts, -+ bytes memory data -+ ) public virtual override { -+ require( -+ from == _msgSender() || isApprovedForAll(from, _msgSender()), -+ "ERC1155: transfer caller is not owner nor approved" -+ ); -+ _safeBatchTransferFrom(from, to, ids, amounts, data); -+ } -+ -+ /** -+ * @dev Transfers `amount` tokens of token type `id` from `from` to `to`. -+ * -+ * Emits a {TransferSingle} event. -+ * -+ * Requirements: -+ * -+ * - `to` cannot be the zero address. -+ * - `from` must have a balance of tokens of type `id` of at least `amount`. -+ * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the -+ * acceptance magic value. -+ */ -+ function _safeTransferFrom( -+ address from, -+ address to, -+ uint256 id, -+ uint256 amount, -+ bytes memory data -+ ) internal virtual { -+ require(to != address(0), "ERC1155: transfer to the zero address"); -+ -+ address operator = _msgSender(); -+ uint256[] memory ids = _asSingletonArray(id); -+ uint256[] memory amounts = _asSingletonArray(amount); -+ -+ _beforeTokenTransfer(operator, from, to, ids, amounts, data); -+ -+ uint256 fromBalance = _balances[id][from]; -+ require(fromBalance >= amount, "ERC1155: insufficient balance for transfer"); -+ unchecked { -+ _balances[id][from] = fromBalance - amount; -+ } -+ _balances[id][to] += amount; -+ -+ emit TransferSingle(operator, from, to, id, amount); -+ -+ _afterTokenTransfer(operator, from, to, ids, amounts, data); -+ -+ _doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data); -+ } -+ -+ /** -+ * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_safeTransferFrom}. -+ * -+ * Emits a {TransferBatch} event. -+ * -+ * Requirements: -+ * -+ * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the -+ * acceptance magic value. -+ */ -+ function _safeBatchTransferFrom( -+ address from, -+ address to, -+ uint256[] memory ids, -+ uint256[] memory amounts, -+ bytes memory data -+ ) internal virtual { -+ require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch"); -+ require(to != address(0), "ERC1155: transfer to the zero address"); -+ -+ address operator = _msgSender(); -+ -+ _beforeTokenTransfer(operator, from, to, ids, amounts, data); -+ -+ for (uint256 i = 0; i < ids.length; ++i) { -+ uint256 id = ids[i]; -+ uint256 amount = amounts[i]; -+ -+ uint256 fromBalance = _balances[id][from]; -+ require(fromBalance >= amount, "ERC1155: insufficient balance for transfer"); -+ unchecked { -+ _balances[id][from] = fromBalance - amount; -+ } -+ _balances[id][to] += amount; -+ } -+ -+ emit TransferBatch(operator, from, to, ids, amounts); -+ -+ _afterTokenTransfer(operator, from, to, ids, amounts, data); -+ -+ _doSafeBatchTransferAcceptanceCheck(operator, from, to, ids, amounts, data); -+ } -+ -+ /** -+ * @dev Sets a new URI for all token types, by relying on the token type ID -+ * substitution mechanism -+ * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP]. -+ * -+ * By this mechanism, any occurrence of the `\{id\}` substring in either the -+ * URI or any of the amounts in the JSON file at said URI will be replaced by -+ * clients with the token type ID. -+ * -+ * For example, the `https://token-cdn-domain/\{id\}.json` URI would be -+ * interpreted by clients as -+ * `https://token-cdn-domain/000000000000000000000000000000000000000000000000000000000004cce0.json` -+ * for token type ID 0x4cce0. -+ * -+ * See {uri}. -+ * -+ * Because these URIs cannot be meaningfully represented by the {URI} event, -+ * this function emits no events. -+ */ -+ function _setURI(string memory newuri) internal virtual { -+ _uri = newuri; -+ } -+ -+ /** -+ * @dev Creates `amount` tokens of token type `id`, and assigns them to `to`. -+ * -+ * Emits a {TransferSingle} event. -+ * -+ * Requirements: -+ * -+ * - `to` cannot be the zero address. -+ * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the -+ * acceptance magic value. -+ */ -+ function _mint( -+ address to, -+ uint256 id, -+ uint256 amount, -+ bytes memory data -+ ) internal virtual { -+ require(to != address(0), "ERC1155: mint to the zero address"); -+ -+ address operator = _msgSender(); -+ uint256[] memory ids = _asSingletonArray(id); -+ uint256[] memory amounts = _asSingletonArray(amount); -+ -+ _beforeTokenTransfer(operator, address(0), to, ids, amounts, data); -+ -+ _balances[id][to] += amount; -+ emit TransferSingle(operator, address(0), to, id, amount); -+ -+ _afterTokenTransfer(operator, address(0), to, ids, amounts, data); -+ -+ _doSafeTransferAcceptanceCheck(operator, address(0), to, id, amount, data); -+ } -+ -+ /** -+ * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}. -+ * -+ * Emits a {TransferBatch} event. -+ * -+ * Requirements: -+ * -+ * - `ids` and `amounts` must have the same length. -+ * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the -+ * acceptance magic value. -+ */ -+ function _mintBatch( -+ address to, -+ uint256[] memory ids, -+ uint256[] memory amounts, -+ bytes memory data -+ ) internal virtual { -+ require(to != address(0), "ERC1155: mint to the zero address"); -+ require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch"); -+ -+ address operator = _msgSender(); -+ -+ _beforeTokenTransfer(operator, address(0), to, ids, amounts, data); -+ -+ for (uint256 i = 0; i < ids.length; i++) { -+ _balances[ids[i]][to] += amounts[i]; -+ } -+ -+ emit TransferBatch(operator, address(0), to, ids, amounts); -+ -+ _afterTokenTransfer(operator, address(0), to, ids, amounts, data); -+ -+ _doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data); -+ } -+ -+ /** -+ * @dev Destroys `amount` tokens of token type `id` from `from` -+ * -+ * Emits a {TransferSingle} event. -+ * -+ * Requirements: -+ * -+ * - `from` cannot be the zero address. -+ * - `from` must have at least `amount` tokens of token type `id`. -+ */ -+ function _burn( -+ address from, -+ uint256 id, -+ uint256 amount -+ ) internal virtual { -+ require(from != address(0), "ERC1155: burn from the zero address"); -+ -+ address operator = _msgSender(); -+ uint256[] memory ids = _asSingletonArray(id); -+ uint256[] memory amounts = _asSingletonArray(amount); -+ -+ _beforeTokenTransfer(operator, from, address(0), ids, amounts, ""); -+ -+ uint256 fromBalance = _balances[id][from]; -+ require(fromBalance >= amount, "ERC1155: burn amount exceeds balance"); -+ unchecked { -+ _balances[id][from] = fromBalance - amount; -+ } -+ -+ emit TransferSingle(operator, from, address(0), id, amount); -+ -+ _afterTokenTransfer(operator, from, address(0), ids, amounts, ""); -+ } -+ -+ /** -+ * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}. -+ * -+ * Emits a {TransferBatch} event. -+ * -+ * Requirements: -+ * -+ * - `ids` and `amounts` must have the same length. -+ */ -+ function _burnBatch( -+ address from, -+ uint256[] memory ids, -+ uint256[] memory amounts -+ ) internal virtual { -+ require(from != address(0), "ERC1155: burn from the zero address"); -+ require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch"); -+ -+ address operator = _msgSender(); -+ -+ _beforeTokenTransfer(operator, from, address(0), ids, amounts, ""); -+ -+ for (uint256 i = 0; i < ids.length; i++) { -+ uint256 id = ids[i]; -+ uint256 amount = amounts[i]; -+ -+ uint256 fromBalance = _balances[id][from]; -+ require(fromBalance >= amount, "ERC1155: burn amount exceeds balance"); -+ unchecked { -+ _balances[id][from] = fromBalance - amount; -+ } -+ } -+ -+ emit TransferBatch(operator, from, address(0), ids, amounts); -+ -+ _afterTokenTransfer(operator, from, address(0), ids, amounts, ""); -+ } -+ -+ /** -+ * @dev Approve `operator` to operate on all of `owner` tokens -+ * -+ * Emits an {ApprovalForAll} event. -+ */ -+ function _setApprovalForAll( -+ address owner, -+ address operator, -+ bool approved -+ ) internal virtual { -+ require(owner != operator, "ERC1155: setting approval status for self"); -+ _operatorApprovals[owner][operator] = approved; -+ emit ApprovalForAll(owner, operator, approved); -+ } -+ -+ /** -+ * @dev Hook that is called before any token transfer. This includes minting -+ * and burning, as well as batched variants. -+ * -+ * The same hook is called on both single and batched variants. For single -+ * transfers, the length of the `ids` and `amounts` arrays will be 1. -+ * -+ * Calling conditions (for each `id` and `amount` pair): -+ * -+ * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens -+ * of token type `id` will be transferred to `to`. -+ * - When `from` is zero, `amount` tokens of token type `id` will be minted -+ * for `to`. -+ * - when `to` is zero, `amount` of ``from``'s tokens of token type `id` -+ * will be burned. -+ * - `from` and `to` are never both zero. -+ * - `ids` and `amounts` have the same, non-zero length. -+ * -+ * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. -+ */ -+ function _beforeTokenTransfer( -+ address operator, -+ address from, -+ address to, -+ uint256[] memory ids, -+ uint256[] memory amounts, -+ bytes memory data -+ ) internal virtual {} -+ -+ /** -+ * @dev Hook that is called after any token transfer. This includes minting -+ * and burning, as well as batched variants. -+ * -+ * The same hook is called on both single and batched variants. For single -+ * transfers, the length of the `id` and `amount` arrays will be 1. -+ * -+ * Calling conditions (for each `id` and `amount` pair): -+ * -+ * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens -+ * of token type `id` will be transferred to `to`. -+ * - When `from` is zero, `amount` tokens of token type `id` will be minted -+ * for `to`. -+ * - when `to` is zero, `amount` of ``from``'s tokens of token type `id` -+ * will be burned. -+ * - `from` and `to` are never both zero. -+ * - `ids` and `amounts` have the same, non-zero length. -+ * -+ * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. -+ */ -+ function _afterTokenTransfer( -+ address operator, -+ address from, -+ address to, -+ uint256[] memory ids, -+ uint256[] memory amounts, -+ bytes memory data -+ ) internal virtual {} -+ -+ function _doSafeTransferAcceptanceCheck( -+ address operator, -+ address from, -+ address to, -+ uint256 id, -+ uint256 amount, -+ bytes memory data -+ ) private { -+ if (to.isContract()) { -+ try IERC1155Receiver(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) { -+ if (response != IERC1155Receiver.onERC1155Received.selector) { -+ revert("ERC1155: ERC1155Receiver rejected tokens"); -+ } -+ } catch Error(string memory reason) { -+ revert(reason); -+ } catch { -+ revert("ERC1155: transfer to non ERC1155Receiver implementer"); -+ } -+ } -+ } -+ -+ function _doSafeBatchTransferAcceptanceCheck( -+ address operator, -+ address from, -+ address to, -+ uint256[] memory ids, -+ uint256[] memory amounts, -+ bytes memory data -+ ) private { -+ if (to.isContract()) { -+ try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns ( -+ bytes4 response -+ ) { -+ if (response != IERC1155Receiver.onERC1155BatchReceived.selector) { -+ revert("ERC1155: ERC1155Receiver rejected tokens"); -+ } -+ } catch Error(string memory reason) { -+ revert(reason); -+ } catch { -+ revert("ERC1155: transfer to non ERC1155Receiver implementer"); -+ } -+ } -+ } -+ -+ function _asSingletonArray(uint256 element) private pure returns (uint256[] memory) { -+ uint256[] memory array = new uint256[](1); -+ array[0] = element; -+ -+ return array; -+ } -+} diff -ruN token/ERC20/ERC20.sol token/ERC20/ERC20.sol --- token/ERC20/ERC20.sol 2022-05-25 15:36:58.853363841 -0400 -+++ token/ERC20/ERC20.sol 2022-05-25 15:37:51.044083806 -0400 ++++ token/ERC20/ERC20.sol 2022-05-25 16:04:57.725255723 -0400 @@ -277,7 +277,7 @@ * - `account` cannot be the zero address. * - `account` must have at least `amount` tokens. @@ -1964,7 +207,7 @@ diff -ruN token/ERC20/ERC20.sol token/ERC20/ERC20.sol /** diff -ruN token/ERC20/extensions/ERC20FlashMint.sol token/ERC20/extensions/ERC20FlashMint.sol --- token/ERC20/extensions/ERC20FlashMint.sol 2022-05-25 15:36:58.853363841 -0400 -+++ token/ERC20/extensions/ERC20FlashMint.sol 2022-05-25 15:37:51.044083806 -0400 ++++ token/ERC20/extensions/ERC20FlashMint.sol 2022-05-25 16:04:57.725255723 -0400 @@ -40,9 +40,11 @@ require(token == address(this), "ERC20FlashMint: wrong token"); // silence warning about unused variable without the addition of bytecode. @@ -1978,109 +221,9 @@ diff -ruN token/ERC20/extensions/ERC20FlashMint.sol token/ERC20/extensions/ERC20 /** * @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 -ruN token/ERC20/extensions/ERC20FlashMint.sol.orig token/ERC20/extensions/ERC20FlashMint.sol.orig ---- token/ERC20/extensions/ERC20FlashMint.sol.orig 1969-12-31 19:00:00.000000000 -0500 -+++ token/ERC20/extensions/ERC20FlashMint.sol.orig 2022-05-25 15:37:51.036084000 -0400 -@@ -0,0 +1,96 @@ -+// SPDX-License-Identifier: MIT -+// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/extensions/ERC20FlashMint.sol) -+ -+pragma solidity ^0.8.0; -+ -+import "../../../interfaces/IERC3156FlashBorrower.sol"; -+import "../../../interfaces/IERC3156FlashLender.sol"; -+import "../ERC20.sol"; -+ -+/** -+ * @dev Implementation of the ERC3156 Flash loans extension, as defined in -+ * https://eips.ethereum.org/EIPS/eip-3156[ERC-3156]. -+ * -+ * Adds the {flashLoan} method, which provides flash loan support at the token -+ * level. By default there is no fee, but this can be changed by overriding {flashFee}. -+ * -+ * _Available since v4.1._ -+ */ -+abstract contract ERC20FlashMint is ERC20, IERC3156FlashLender { -+ bytes32 private constant _RETURN_VALUE = keccak256("ERC3156FlashBorrower.onFlashLoan"); -+ -+ /** -+ * @dev Returns the maximum amount of tokens available for loan. -+ * @param token The address of the token that is requested. -+ * @return The amount of token that can be loaned. -+ */ -+ function maxFlashLoan(address token) public view virtual override returns (uint256) { -+ return token == address(this) ? type(uint256).max - ERC20.totalSupply() : 0; -+ } -+ -+ /** -+ * @dev Returns the fee applied when doing flash loans. By default this -+ * implementation has 0 fees. This function can be overloaded to make -+ * the flash loan mechanism deflationary. -+ * @param token The token to be flash loaned. -+ * @param amount The amount of tokens to be loaned. -+ * @return The fees applied to the corresponding flash loan. -+ */ -+ function flashFee(address token, uint256 amount) public view virtual override returns (uint256) { -+ require(token == address(this), "ERC20FlashMint: wrong token"); -+ // silence warning about unused variable without the addition of bytecode. -+ amount; -+ return 0; -+ } -+ -+ /** -+ * @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. -+ * This function can be overloaded to change the fee receiver. -+ * @return The address for which the flash fee will be sent to. -+ */ -+ function _flashFeeReceiver() internal view virtual returns (address) { -+ return address(0); -+ } -+ -+ /** -+ * @dev Performs a flash loan. New tokens are minted and sent to the -+ * `receiver`, who is required to implement the {IERC3156FlashBorrower} -+ * interface. By the end of the flash loan, the receiver is expected to own -+ * amount + fee tokens and have them approved back to the token contract itself so -+ * they can be burned. -+ * @param receiver The receiver of the flash loan. Should implement the -+ * {IERC3156FlashBorrower.onFlashLoan} interface. -+ * @param token The token to be flash loaned. Only `address(this)` is -+ * supported. -+ * @param amount The amount of tokens to be loaned. -+ * @param data An arbitrary datafield that is passed to the receiver. -+ * @return `true` if the flash loan was successful. -+ */ -+ // This function can reenter, but it doesn't pose a risk because it always preserves the property that the amount -+ // minted at the beginning is always recovered and burned at the end, or else the entire function will revert. -+ // slither-disable-next-line reentrancy-no-eth -+ function flashLoan( -+ IERC3156FlashBorrower receiver, -+ address token, -+ uint256 amount, -+ bytes calldata data -+ ) public virtual override returns (bool) { -+ require(amount <= maxFlashLoan(token), "ERC20FlashMint: amount exceeds maxFlashLoan"); -+ uint256 fee = flashFee(token, amount); -+ _mint(address(receiver), amount); -+ require( -+ receiver.onFlashLoan(msg.sender, token, amount, fee, data) == _RETURN_VALUE, -+ "ERC20FlashMint: invalid return value" -+ ); -+ address flashFeeReceiver = _flashFeeReceiver(); -+ _spendAllowance(address(receiver), address(this), amount + fee); -+ if (fee == 0 || flashFeeReceiver == address(0)) { -+ _burn(address(receiver), amount + fee); -+ } else { -+ _burn(address(receiver), amount); -+ _transfer(address(receiver), flashFeeReceiver, fee); -+ } -+ return true; -+ } -+} diff -ruN token/ERC20/extensions/ERC20Votes.sol token/ERC20/extensions/ERC20Votes.sol --- token/ERC20/extensions/ERC20Votes.sol 2022-03-02 13:56:14.831535075 -0500 -+++ token/ERC20/extensions/ERC20Votes.sol 2022-05-25 15:37:51.044083806 -0400 ++++ token/ERC20/extensions/ERC20Votes.sol 2022-05-25 16:04:57.725255723 -0400 @@ -33,8 +33,8 @@ bytes32 private constant _DELEGATION_TYPEHASH = keccak256("Delegation(address delegatee,uint256 nonce,uint256 expiry)"); @@ -2094,7 +237,7 @@ diff -ruN token/ERC20/extensions/ERC20Votes.sol token/ERC20/extensions/ERC20Vote /** diff -ruN token/ERC20/extensions/ERC20Wrapper.sol token/ERC20/extensions/ERC20Wrapper.sol --- token/ERC20/extensions/ERC20Wrapper.sol 2022-05-25 15:36:58.853363841 -0400 -+++ token/ERC20/extensions/ERC20Wrapper.sol 2022-05-25 15:37:51.044083806 -0400 ++++ token/ERC20/extensions/ERC20Wrapper.sol 2022-05-25 16:04:57.733255587 -0400 @@ -55,7 +55,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. @@ -2104,76 +247,9 @@ diff -ruN token/ERC20/extensions/ERC20Wrapper.sol token/ERC20/extensions/ERC20Wr uint256 value = underlying.balanceOf(address(this)) - totalSupply(); _mint(account, value); return value; -diff -ruN token/ERC20/extensions/ERC20Wrapper.sol.orig token/ERC20/extensions/ERC20Wrapper.sol.orig ---- token/ERC20/extensions/ERC20Wrapper.sol.orig 1969-12-31 19:00:00.000000000 -0500 -+++ token/ERC20/extensions/ERC20Wrapper.sol.orig 2022-05-25 15:37:51.036084000 -0400 -@@ -0,0 +1,63 @@ -+// SPDX-License-Identifier: MIT -+// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/extensions/ERC20Wrapper.sol) -+ -+pragma solidity ^0.8.0; -+ -+import "../ERC20.sol"; -+import "../utils/SafeERC20.sol"; -+ -+/** -+ * @dev Extension of the ERC20 token contract to support token wrapping. -+ * -+ * Users can deposit and withdraw "underlying tokens" and receive a matching number of "wrapped tokens". This is useful -+ * in conjunction with other modules. For example, combining this wrapping mechanism with {ERC20Votes} will allow the -+ * wrapping of an existing "basic" ERC20 into a governance token. -+ * -+ * _Available since v4.2._ -+ */ -+abstract contract ERC20Wrapper is ERC20 { -+ IERC20 public immutable underlying; -+ -+ constructor(IERC20 underlyingToken) { -+ underlying = underlyingToken; -+ } -+ -+ /** -+ * @dev See {ERC20-decimals}. -+ */ -+ function decimals() public view virtual override returns (uint8) { -+ try IERC20Metadata(address(underlying)).decimals() returns (uint8 value) { -+ return value; -+ } catch { -+ return super.decimals(); -+ } -+ } -+ -+ /** -+ * @dev Allow a user to deposit underlying tokens and mint the corresponding number of wrapped tokens. -+ */ -+ function depositFor(address account, uint256 amount) public virtual returns (bool) { -+ SafeERC20.safeTransferFrom(underlying, _msgSender(), address(this), amount); -+ _mint(account, amount); -+ return true; -+ } -+ -+ /** -+ * @dev Allow a user to burn a number of wrapped tokens and withdraw the corresponding number of underlying tokens. -+ */ -+ function withdrawTo(address account, uint256 amount) public virtual returns (bool) { -+ _burn(_msgSender(), amount); -+ SafeERC20.safeTransfer(underlying, account, amount); -+ return true; -+ } -+ -+ /** -+ * @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) { -+ uint256 value = underlying.balanceOf(address(this)) - totalSupply(); -+ _mint(account, value); -+ return value; -+ } -+} diff -ruN token/ERC721/extensions/draft-ERC721Votes.sol token/ERC721/extensions/draft-ERC721Votes.sol --- token/ERC721/extensions/draft-ERC721Votes.sol 2022-05-25 15:36:58.853363841 -0400 -+++ token/ERC721/extensions/draft-ERC721Votes.sol 2022-05-25 15:59:49.842532468 -0400 ++++ token/ERC721/extensions/draft-ERC721Votes.sol 2022-05-25 16:04:57.733255587 -0400 @@ -34,7 +34,7 @@ /** * @dev Returns the balance of `account`. @@ -2183,53 +259,9 @@ diff -ruN token/ERC721/extensions/draft-ERC721Votes.sol token/ERC721/extensions/ return balanceOf(account); } } -diff -ruN token/ERC721/extensions/draft-ERC721Votes.sol.orig token/ERC721/extensions/draft-ERC721Votes.sol.orig ---- token/ERC721/extensions/draft-ERC721Votes.sol.orig 1969-12-31 19:00:00.000000000 -0500 -+++ token/ERC721/extensions/draft-ERC721Votes.sol.orig 2022-05-25 15:37:51.044083806 -0400 -@@ -0,0 +1,40 @@ -+// SPDX-License-Identifier: MIT -+// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/extensions/draft-ERC721Votes.sol) -+ -+pragma solidity ^0.8.0; -+ -+import "../ERC721.sol"; -+import "../../../governance/utils/Votes.sol"; -+ -+/** -+ * @dev Extension of ERC721 to support voting and delegation as implemented by {Votes}, where each individual NFT counts -+ * as 1 vote unit. -+ * -+ * Tokens do not count as votes until they are delegated, because votes must be tracked which incurs an additional cost -+ * on every transfer. Token holders can either delegate to a trusted representative who will decide how to make use of -+ * the votes in governance decisions, or they can delegate to themselves to be their own representative. -+ * -+ * _Available since v4.5._ -+ */ -+abstract contract ERC721Votes is ERC721, Votes { -+ /** -+ * @dev Adjusts votes when tokens are transferred. -+ * -+ * Emits a {Votes-DelegateVotesChanged} event. -+ */ -+ function _afterTokenTransfer( -+ address from, -+ address to, -+ uint256 tokenId -+ ) internal virtual override { -+ _transferVotingUnits(from, to, 1); -+ super._afterTokenTransfer(from, to, tokenId); -+ } -+ -+ /** -+ * @dev Returns the balance of `account`. -+ */ -+ function _getVotingUnits(address account) internal view virtual override returns (uint256) { -+ return balanceOf(account); -+ } -+} diff -ruN utils/Address.sol utils/Address.sol --- utils/Address.sol 2022-05-25 15:36:58.853363841 -0400 -+++ utils/Address.sol 2022-05-25 15:37:51.044083806 -0400 ++++ utils/Address.sol 2022-05-25 16:04:57.733255587 -0400 @@ -131,6 +131,7 @@ uint256 value, string memory errorMessage