This commit is contained in:
dexorder
2024-10-17 02:42:28 -04:00
commit 25def69c66
878 changed files with 112489 additions and 0 deletions

View File

@@ -0,0 +1,34 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {AccessManaged} from "../access/manager/AccessManaged.sol";
import {StorageSlot} from "../utils/StorageSlot.sol";
abstract contract AccessManagedTarget is AccessManaged {
event CalledRestricted(address caller);
event CalledUnrestricted(address caller);
event CalledFallback(address caller);
function fnRestricted() public restricted {
emit CalledRestricted(msg.sender);
}
function fnUnrestricted() public {
emit CalledUnrestricted(msg.sender);
}
function setIsConsumingScheduledOp(bool isConsuming, bytes32 slot) external {
// Memory layout is 0x....<_consumingSchedule (boolean)><authority (address)>
bytes32 mask = bytes32(uint256(1 << 160));
if (isConsuming) {
StorageSlot.getBytes32Slot(slot).value |= mask;
} else {
StorageSlot.getBytes32Slot(slot).value &= ~mask;
}
}
fallback() external {
emit CalledFallback(msg.sender);
}
}

View File

@@ -0,0 +1,127 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {Arrays} from "../utils/Arrays.sol";
contract Uint256ArraysMock {
using Arrays for uint256[];
uint256[] private _array;
constructor(uint256[] memory array) {
_array = array;
}
function findUpperBound(uint256 value) external view returns (uint256) {
return _array.findUpperBound(value);
}
function lowerBound(uint256 value) external view returns (uint256) {
return _array.lowerBound(value);
}
function upperBound(uint256 value) external view returns (uint256) {
return _array.upperBound(value);
}
function lowerBoundMemory(uint256[] memory array, uint256 value) external pure returns (uint256) {
return array.lowerBoundMemory(value);
}
function upperBoundMemory(uint256[] memory array, uint256 value) external pure returns (uint256) {
return array.upperBoundMemory(value);
}
function unsafeAccess(uint256 pos) external view returns (uint256) {
return _array.unsafeAccess(pos).value;
}
function sort(uint256[] memory array) external pure returns (uint256[] memory) {
return array.sort();
}
function sortReverse(uint256[] memory array) external pure returns (uint256[] memory) {
return array.sort(_reverse);
}
function _reverse(uint256 a, uint256 b) private pure returns (bool) {
return a > b;
}
function unsafeSetLength(uint256 newLength) external {
_array.unsafeSetLength(newLength);
}
function length() external view returns (uint256) {
return _array.length;
}
}
contract AddressArraysMock {
using Arrays for address[];
address[] private _array;
constructor(address[] memory array) {
_array = array;
}
function unsafeAccess(uint256 pos) external view returns (address) {
return _array.unsafeAccess(pos).value;
}
function sort(address[] memory array) external pure returns (address[] memory) {
return array.sort();
}
function sortReverse(address[] memory array) external pure returns (address[] memory) {
return array.sort(_reverse);
}
function _reverse(address a, address b) private pure returns (bool) {
return uint160(a) > uint160(b);
}
function unsafeSetLength(uint256 newLength) external {
_array.unsafeSetLength(newLength);
}
function length() external view returns (uint256) {
return _array.length;
}
}
contract Bytes32ArraysMock {
using Arrays for bytes32[];
bytes32[] private _array;
constructor(bytes32[] memory array) {
_array = array;
}
function unsafeAccess(uint256 pos) external view returns (bytes32) {
return _array.unsafeAccess(pos).value;
}
function sort(bytes32[] memory array) external pure returns (bytes32[] memory) {
return array.sort();
}
function sortReverse(bytes32[] memory array) external pure returns (bytes32[] memory) {
return array.sort(_reverse);
}
function _reverse(bytes32 a, bytes32 b) private pure returns (bool) {
return uint256(a) > uint256(b);
}
function unsafeSetLength(uint256 newLength) external {
_array.unsafeSetLength(newLength);
}
function length() external view returns (uint256) {
return _array.length;
}
}

View File

@@ -0,0 +1,69 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {IAccessManaged} from "../access/manager/IAccessManaged.sol";
import {IAuthority} from "../access/manager/IAuthority.sol";
contract NotAuthorityMock is IAuthority {
function canCall(address /* caller */, address /* target */, bytes4 /* selector */) external pure returns (bool) {
revert("AuthorityNoDelayMock: not implemented");
}
}
contract AuthorityNoDelayMock is IAuthority {
bool _immediate;
function canCall(
address /* caller */,
address /* target */,
bytes4 /* selector */
) external view returns (bool immediate) {
return _immediate;
}
function _setImmediate(bool immediate) external {
_immediate = immediate;
}
}
contract AuthorityDelayMock {
bool _immediate;
uint32 _delay;
function canCall(
address /* caller */,
address /* target */,
bytes4 /* selector */
) external view returns (bool immediate, uint32 delay) {
return (_immediate, _delay);
}
function _setImmediate(bool immediate) external {
_immediate = immediate;
}
function _setDelay(uint32 delay) external {
_delay = delay;
}
}
contract AuthorityNoResponse {
function canCall(address /* caller */, address /* target */, bytes4 /* selector */) external view {}
}
contract AuthorityObserveIsConsuming {
event ConsumeScheduledOpCalled(address caller, bytes data, bytes4 isConsuming);
function canCall(
address /* caller */,
address /* target */,
bytes4 /* selector */
) external pure returns (bool immediate, uint32 delay) {
return (false, 1);
}
function consumeScheduledOp(address caller, bytes memory data) public {
emit ConsumeScheduledOpCalled(caller, data, IAccessManaged(msg.sender).isConsumingScheduledOp());
}
}

View File

@@ -0,0 +1,19 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {Base64} from "../utils/Base64.sol";
contract Base64Dirty {
struct A {
uint256 value;
}
function encode(bytes memory input) public pure returns (string memory) {
A memory unused = A({value: type(uint256).max});
// To silence warning
unused;
return Base64.encode(input);
}
}

View File

@@ -0,0 +1,73 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
contract CallReceiverMock {
event MockFunctionCalled();
event MockFunctionCalledWithArgs(uint256 a, uint256 b);
uint256[] private _array;
function mockFunction() public payable returns (string memory) {
emit MockFunctionCalled();
return "0x1234";
}
function mockFunctionEmptyReturn() public payable {
emit MockFunctionCalled();
}
function mockFunctionWithArgs(uint256 a, uint256 b) public payable returns (string memory) {
emit MockFunctionCalledWithArgs(a, b);
return "0x1234";
}
function mockFunctionNonPayable() public returns (string memory) {
emit MockFunctionCalled();
return "0x1234";
}
function mockStaticFunction() public pure returns (string memory) {
return "0x1234";
}
function mockFunctionRevertsNoReason() public payable {
revert();
}
function mockFunctionRevertsReason() public payable {
revert("CallReceiverMock: reverting");
}
function mockFunctionThrows() public payable {
assert(false);
}
function mockFunctionOutOfGas() public payable {
for (uint256 i = 0; ; ++i) {
_array.push(i);
}
}
function mockFunctionWritesStorage(bytes32 slot, bytes32 value) public returns (string memory) {
assembly {
sstore(slot, value)
}
return "0x1234";
}
}
contract CallReceiverMockTrustingForwarder is CallReceiverMock {
address private _trustedForwarder;
constructor(address trustedForwarder_) {
_trustedForwarder = trustedForwarder_;
}
function isTrustedForwarder(address forwarder) public view virtual returns (bool) {
return forwarder == _trustedForwarder;
}
}

View File

@@ -0,0 +1,35 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {Context} from "../utils/Context.sol";
contract ContextMock is Context {
event Sender(address sender);
function msgSender() public {
emit Sender(_msgSender());
}
event Data(bytes data, uint256 integerValue, string stringValue);
function msgData(uint256 integerValue, string memory stringValue) public {
emit Data(_msgData(), integerValue, stringValue);
}
event DataShort(bytes data);
function msgDataShort() public {
emit DataShort(_msgData());
}
}
contract ContextMockCaller {
function callSender(ContextMock context) public {
context.msgSender();
}
function callData(ContextMock context, uint256 integerValue, string memory stringValue) public {
context.msgData(integerValue, stringValue);
}
}

View File

@@ -0,0 +1,65 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {ERC1967Utils} from "../proxy/ERC1967/ERC1967Utils.sol";
import {StorageSlot} from "../utils/StorageSlot.sol";
abstract contract Impl {
function version() public pure virtual returns (string memory);
}
contract DummyImplementation {
uint256 public value;
string public text;
uint256[] public values;
function initializeNonPayable() public {
value = 10;
}
function initializePayable() public payable {
value = 100;
}
function initializeNonPayableWithValue(uint256 _value) public {
value = _value;
}
function initializePayableWithValue(uint256 _value) public payable {
value = _value;
}
function initialize(uint256 _value, string memory _text, uint256[] memory _values) public {
value = _value;
text = _text;
values = _values;
}
function get() public pure returns (bool) {
return true;
}
function version() public pure virtual returns (string memory) {
return "V1";
}
function reverts() public pure {
require(false, "DummyImplementation reverted");
}
// Use for forcing an unsafe TransparentUpgradeableProxy admin override
function unsafeOverrideAdmin(address newAdmin) public {
StorageSlot.getAddressSlot(ERC1967Utils.ADMIN_SLOT).value = newAdmin;
}
}
contract DummyImplementationV2 is DummyImplementation {
function migrate(uint256 newVal) public payable {
value = newVal;
}
function version() public pure override returns (string memory) {
return "V2";
}
}

View File

@@ -0,0 +1,16 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {ECDSA} from "../utils/cryptography/ECDSA.sol";
import {EIP712} from "../utils/cryptography/EIP712.sol";
abstract contract EIP712Verifier is EIP712 {
function verify(bytes memory signature, address signer, address mailTo, string memory mailContents) external view {
bytes32 digest = _hashTypedDataV4(
keccak256(abi.encode(keccak256("Mail(address to,string contents)"), mailTo, keccak256(bytes(mailContents))))
);
address recoveredSigner = ECDSA.recover(digest, signature);
require(recoveredSigner == signer);
}
}

View File

@@ -0,0 +1,24 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {Ownable} from "../access/Ownable.sol";
import {IERC1271} from "../interfaces/IERC1271.sol";
import {ECDSA} from "../utils/cryptography/ECDSA.sol";
contract ERC1271WalletMock is Ownable, IERC1271 {
constructor(address originalOwner) Ownable(originalOwner) {}
function isValidSignature(bytes32 hash, bytes memory signature) public view returns (bytes4 magicValue) {
return ECDSA.recover(hash, signature) == owner() ? this.isValidSignature.selector : bytes4(0);
}
}
contract ERC1271MaliciousMock is IERC1271 {
function isValidSignature(bytes32, bytes memory) public pure returns (bytes4) {
assembly {
mstore(0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
return(0, 32)
}
}
}

View File

@@ -0,0 +1,58 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {IERC165} from "../../utils/introspection/IERC165.sol";
/**
* https://eips.ethereum.org/EIPS/eip-214#specification
* From the specification:
* > Any attempts to make state-changing operations inside an execution instance with STATIC set to true will instead
* throw an exception.
* > These operations include [...], LOG0, LOG1, LOG2, [...]
*
* therefore, because this contract is staticcall'd we need to not emit events (which is how solidity-coverage works)
* solidity-coverage ignores the /mocks folder, so we duplicate its implementation here to avoid instrumenting it
*/
contract SupportsInterfaceWithLookupMock is IERC165 {
/*
* bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7
*/
bytes4 public constant INTERFACE_ID_ERC165 = 0x01ffc9a7;
/**
* @dev A mapping of interface id to whether or not it's supported.
*/
mapping(bytes4 interfaceId => bool) private _supportedInterfaces;
/**
* @dev A contract implementing SupportsInterfaceWithLookup
* implement ERC-165 itself.
*/
constructor() {
_registerInterface(INTERFACE_ID_ERC165);
}
/**
* @dev Implement supportsInterface(bytes4) using a lookup table.
*/
function supportsInterface(bytes4 interfaceId) public view override returns (bool) {
return _supportedInterfaces[interfaceId];
}
/**
* @dev Private method for registering an interface.
*/
function _registerInterface(bytes4 interfaceId) internal {
require(interfaceId != 0xffffffff, "ERC165InterfacesSupported: invalid interface id");
_supportedInterfaces[interfaceId] = true;
}
}
contract ERC165InterfacesSupported is SupportsInterfaceWithLookupMock {
constructor(bytes4[] memory interfaceIds) {
for (uint256 i = 0; i < interfaceIds.length; i++) {
_registerInterface(interfaceIds[i]);
}
}
}

View File

@@ -0,0 +1,12 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
contract ERC165MaliciousData {
function supportsInterface(bytes4) public pure returns (bool) {
assembly {
mstore(0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
return(0, 32)
}
}
}

View File

@@ -0,0 +1,7 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
contract ERC165MissingData {
function supportsInterface(bytes4 interfaceId) public view {} // missing return
}

View File

@@ -0,0 +1,5 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
contract ERC165NotSupported {}

View File

@@ -0,0 +1,18 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {IERC165} from "../../utils/introspection/IERC165.sol";
contract ERC165ReturnBombMock is IERC165 {
function supportsInterface(bytes4 interfaceId) public pure override returns (bool) {
if (interfaceId == type(IERC165).interfaceId) {
assembly {
mstore(0, 1)
}
}
assembly {
return(0, 101500)
}
}
}

View File

@@ -0,0 +1,28 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {ContextMock} from "./ContextMock.sol";
import {Context} from "../utils/Context.sol";
import {Multicall} from "../utils/Multicall.sol";
import {ERC2771Context} from "../metatx/ERC2771Context.sol";
// By inheriting from ERC2771Context, Context's internal functions are overridden automatically
contract ERC2771ContextMock is ContextMock, ERC2771Context, Multicall {
/// @custom:oz-upgrades-unsafe-allow constructor
constructor(address trustedForwarder) ERC2771Context(trustedForwarder) {
emit Sender(_msgSender()); // _msgSender() should be accessible during construction
}
function _msgSender() internal view override(Context, ERC2771Context) returns (address) {
return ERC2771Context._msgSender();
}
function _msgData() internal view override(Context, ERC2771Context) returns (bytes calldata) {
return ERC2771Context._msgData();
}
function _contextSuffixLength() internal view override(Context, ERC2771Context) returns (uint256) {
return ERC2771Context._contextSuffixLength();
}
}

View File

@@ -0,0 +1,53 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {IERC20} from "../token/ERC20/IERC20.sol";
import {IERC3156FlashBorrower} from "../interfaces/IERC3156.sol";
import {Address} from "../utils/Address.sol";
/**
* @dev WARNING: this IERC3156FlashBorrower mock implementation is for testing purposes ONLY.
* Writing a secure flash lock borrower is not an easy task, and should be done with the utmost care.
* This is not an example of how it should be done, and no pattern present in this mock should be considered secure.
* Following best practices, always have your contract properly audited before using them to manipulate important funds on
* live networks.
*/
contract ERC3156FlashBorrowerMock is IERC3156FlashBorrower {
bytes32 internal constant _RETURN_VALUE = keccak256("ERC3156FlashBorrower.onFlashLoan");
bool immutable _enableApprove;
bool immutable _enableReturn;
event BalanceOf(address token, address account, uint256 value);
event TotalSupply(address token, uint256 value);
constructor(bool enableReturn, bool enableApprove) {
_enableApprove = enableApprove;
_enableReturn = enableReturn;
}
function onFlashLoan(
address /*initiator*/,
address token,
uint256 amount,
uint256 fee,
bytes calldata data
) public returns (bytes32) {
require(msg.sender == token);
emit BalanceOf(token, address(this), IERC20(token).balanceOf(address(this)));
emit TotalSupply(token, IERC20(token).totalSupply());
if (data.length > 0) {
// WARNING: This code is for testing purposes only! Do not use.
Address.functionCall(token, data);
}
if (_enableApprove) {
IERC20(token).approve(token, amount + fee);
}
return _enableReturn ? _RETURN_VALUE : bytes32(0);
}
}

View File

@@ -0,0 +1,17 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
contract EtherReceiverMock {
bool private _acceptEther;
function setAcceptEther(bool acceptEther) public {
_acceptEther = acceptEther;
}
receive() external payable {
if (!_acceptEther) {
revert();
}
}
}

View File

@@ -0,0 +1,130 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {Initializable} from "../proxy/utils/Initializable.sol";
/**
* @title InitializableMock
* @dev This contract is a mock to test initializable functionality
*/
contract InitializableMock is Initializable {
bool public initializerRan;
bool public onlyInitializingRan;
uint256 public x;
function isInitializing() public view returns (bool) {
return _isInitializing();
}
function initialize() public initializer {
initializerRan = true;
}
function initializeOnlyInitializing() public onlyInitializing {
onlyInitializingRan = true;
}
function initializerNested() public initializer {
initialize();
}
function onlyInitializingNested() public initializer {
initializeOnlyInitializing();
}
function initializeWithX(uint256 _x) public payable initializer {
x = _x;
}
function nonInitializable(uint256 _x) public payable {
x = _x;
}
function fail() public pure {
require(false, "InitializableMock forced failure");
}
}
contract ConstructorInitializableMock is Initializable {
bool public initializerRan;
bool public onlyInitializingRan;
constructor() initializer {
initialize();
initializeOnlyInitializing();
}
function initialize() public initializer {
initializerRan = true;
}
function initializeOnlyInitializing() public onlyInitializing {
onlyInitializingRan = true;
}
}
contract ChildConstructorInitializableMock is ConstructorInitializableMock {
bool public childInitializerRan;
constructor() initializer {
childInitialize();
}
function childInitialize() public initializer {
childInitializerRan = true;
}
}
contract ReinitializerMock is Initializable {
uint256 public counter;
function getInitializedVersion() public view returns (uint64) {
return _getInitializedVersion();
}
function initialize() public initializer {
doStuff();
}
function reinitialize(uint64 i) public reinitializer(i) {
doStuff();
}
function nestedReinitialize(uint64 i, uint64 j) public reinitializer(i) {
reinitialize(j);
}
function chainReinitialize(uint64 i, uint64 j) public {
reinitialize(i);
reinitialize(j);
}
function disableInitializers() public {
_disableInitializers();
}
function doStuff() public onlyInitializing {
counter++;
}
}
contract DisableNew is Initializable {
constructor() {
_disableInitializers();
}
}
contract DisableOld is Initializable {
constructor() initializer {}
}
contract DisableBad1 is DisableNew, DisableOld {}
contract DisableBad2 is Initializable {
constructor() initializer {
_disableInitializers();
}
}
contract DisableOk is DisableOld, DisableNew {}

View File

@@ -0,0 +1,44 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {MerkleTree} from "../utils/structs/MerkleTree.sol";
contract MerkleTreeMock {
using MerkleTree for MerkleTree.Bytes32PushTree;
MerkleTree.Bytes32PushTree private _tree;
// This mock only stored the latest root.
// Production contract may want to store historical values.
bytes32 public root;
event LeafInserted(bytes32 leaf, uint256 index, bytes32 root);
function setup(uint8 _depth, bytes32 _zero) public {
root = _tree.setup(_depth, _zero);
}
function push(bytes32 leaf) public {
(uint256 leafIndex, bytes32 currentRoot) = _tree.push(leaf);
emit LeafInserted(leaf, leafIndex, currentRoot);
root = currentRoot;
}
function depth() public view returns (uint256) {
return _tree.depth();
}
// internal state
function nextLeafIndex() public view returns (uint256) {
return _tree._nextLeafIndex;
}
function sides(uint256 i) public view returns (bytes32) {
return _tree._sides[i];
}
function zeros(uint256 i) public view returns (bytes32) {
return _tree._zeros[i];
}
}

View File

@@ -0,0 +1,23 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {ERC20MulticallMock} from "./token/ERC20MulticallMock.sol";
contract MulticallHelper {
function checkReturnValues(
ERC20MulticallMock multicallToken,
address[] calldata recipients,
uint256[] calldata amounts
) external {
bytes[] memory calls = new bytes[](recipients.length);
for (uint256 i = 0; i < recipients.length; i++) {
calls[i] = abi.encodeCall(multicallToken.transfer, (recipients[i], amounts[i]));
}
bytes[] memory results = multicallToken.multicall(calls);
for (uint256 i = 0; i < results.length; i++) {
require(abi.decode(results[i], (bool)));
}
}
}

View File

@@ -0,0 +1,131 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {Initializable} from "../proxy/utils/Initializable.sol";
// Sample contracts showing upgradeability with multiple inheritance.
// Child contract inherits from Father and Mother contracts, and Father extends from Gramps.
//
// Human
// / \
// | Gramps
// | |
// Mother Father
// | |
// -- Child --
/**
* Sample base initializable contract that is a human
*/
contract SampleHuman is Initializable {
bool public isHuman;
function initialize() public initializer {
__SampleHuman_init();
}
// solhint-disable-next-line func-name-mixedcase
function __SampleHuman_init() internal onlyInitializing {
__SampleHuman_init_unchained();
}
// solhint-disable-next-line func-name-mixedcase
function __SampleHuman_init_unchained() internal onlyInitializing {
isHuman = true;
}
}
/**
* Sample base initializable contract that defines a field mother
*/
contract SampleMother is Initializable, SampleHuman {
uint256 public mother;
function initialize(uint256 value) public initializer {
__SampleMother_init(value);
}
// solhint-disable-next-line func-name-mixedcase
function __SampleMother_init(uint256 value) internal onlyInitializing {
__SampleHuman_init();
__SampleMother_init_unchained(value);
}
// solhint-disable-next-line func-name-mixedcase
function __SampleMother_init_unchained(uint256 value) internal onlyInitializing {
mother = value;
}
}
/**
* Sample base initializable contract that defines a field gramps
*/
contract SampleGramps is Initializable, SampleHuman {
string public gramps;
function initialize(string memory value) public initializer {
__SampleGramps_init(value);
}
// solhint-disable-next-line func-name-mixedcase
function __SampleGramps_init(string memory value) internal onlyInitializing {
__SampleHuman_init();
__SampleGramps_init_unchained(value);
}
// solhint-disable-next-line func-name-mixedcase
function __SampleGramps_init_unchained(string memory value) internal onlyInitializing {
gramps = value;
}
}
/**
* Sample base initializable contract that defines a field father and extends from gramps
*/
contract SampleFather is Initializable, SampleGramps {
uint256 public father;
function initialize(string memory _gramps, uint256 _father) public initializer {
__SampleFather_init(_gramps, _father);
}
// solhint-disable-next-line func-name-mixedcase
function __SampleFather_init(string memory _gramps, uint256 _father) internal onlyInitializing {
__SampleGramps_init(_gramps);
__SampleFather_init_unchained(_father);
}
// solhint-disable-next-line func-name-mixedcase
function __SampleFather_init_unchained(uint256 _father) internal onlyInitializing {
father = _father;
}
}
/**
* Child extends from mother, father (gramps)
*/
contract SampleChild is Initializable, SampleMother, SampleFather {
uint256 public child;
function initialize(uint256 _mother, string memory _gramps, uint256 _father, uint256 _child) public initializer {
__SampleChild_init(_mother, _gramps, _father, _child);
}
// solhint-disable-next-line func-name-mixedcase
function __SampleChild_init(
uint256 _mother,
string memory _gramps,
uint256 _father,
uint256 _child
) internal onlyInitializing {
__SampleMother_init(_mother);
__SampleFather_init(_gramps, _father);
__SampleChild_init_unchained(_child);
}
// solhint-disable-next-line func-name-mixedcase
function __SampleChild_init_unchained(uint256 _child) internal onlyInitializing {
child = _child;
}
}

View File

@@ -0,0 +1,31 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {Pausable} from "../utils/Pausable.sol";
contract PausableMock is Pausable {
bool public drasticMeasureTaken;
uint256 public count;
constructor() {
drasticMeasureTaken = false;
count = 0;
}
function normalProcess() external whenNotPaused {
count++;
}
function drasticMeasure() external whenPaused {
drasticMeasureTaken = true;
}
function pause() external {
_pause();
}
function unpause() external {
_unpause();
}
}

View File

@@ -0,0 +1,12 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {Context} from "../utils/Context.sol";
contract ReentrancyAttack is Context {
function callSender(bytes calldata data) public {
(bool success, ) = _msgSender().call(data);
require(success, "ReentrancyAttack: failed call");
}
}

View File

@@ -0,0 +1,50 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {ReentrancyGuard} from "../utils/ReentrancyGuard.sol";
import {ReentrancyAttack} from "./ReentrancyAttack.sol";
contract ReentrancyMock is ReentrancyGuard {
uint256 public counter;
constructor() {
counter = 0;
}
function callback() external nonReentrant {
_count();
}
function countLocalRecursive(uint256 n) public nonReentrant {
if (n > 0) {
_count();
countLocalRecursive(n - 1);
}
}
function countThisRecursive(uint256 n) public nonReentrant {
if (n > 0) {
_count();
(bool success, ) = address(this).call(abi.encodeCall(this.countThisRecursive, (n - 1)));
require(success, "ReentrancyMock: failed call");
}
}
function countAndCall(ReentrancyAttack attacker) public nonReentrant {
_count();
attacker.callSender(abi.encodeCall(this.callback, ()));
}
function _count() private {
counter += 1;
}
function guardedCheckEntered() public nonReentrant {
require(_reentrancyGuardEntered());
}
function unguardedCheckNotEntered() public view {
require(!_reentrancyGuardEntered());
}
}

View File

@@ -0,0 +1,50 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
import {ReentrancyGuardTransient} from "../utils/ReentrancyGuardTransient.sol";
import {ReentrancyAttack} from "./ReentrancyAttack.sol";
contract ReentrancyTransientMock is ReentrancyGuardTransient {
uint256 public counter;
constructor() {
counter = 0;
}
function callback() external nonReentrant {
_count();
}
function countLocalRecursive(uint256 n) public nonReentrant {
if (n > 0) {
_count();
countLocalRecursive(n - 1);
}
}
function countThisRecursive(uint256 n) public nonReentrant {
if (n > 0) {
_count();
(bool success, ) = address(this).call(abi.encodeCall(this.countThisRecursive, (n - 1)));
require(success, "ReentrancyTransientMock: failed call");
}
}
function countAndCall(ReentrancyAttack attacker) public nonReentrant {
_count();
attacker.callSender(abi.encodeCall(this.callback, ()));
}
function _count() private {
counter += 1;
}
function guardedCheckEntered() public nonReentrant {
require(_reentrancyGuardEntered());
}
function unguardedCheckNotEntered() public view {
require(!_reentrancyGuardEntered());
}
}

View File

@@ -0,0 +1,61 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {Initializable} from "../proxy/utils/Initializable.sol";
contract Implementation1 is Initializable {
uint256 internal _value;
function initialize() public initializer {}
function setValue(uint256 _number) public {
_value = _number;
}
}
contract Implementation2 is Initializable {
uint256 internal _value;
function initialize() public initializer {}
function setValue(uint256 _number) public {
_value = _number;
}
function getValue() public view returns (uint256) {
return _value;
}
}
contract Implementation3 is Initializable {
uint256 internal _value;
function initialize() public initializer {}
function setValue(uint256 _number) public {
_value = _number;
}
function getValue(uint256 _number) public view returns (uint256) {
return _value + _number;
}
}
contract Implementation4 is Initializable {
uint256 internal _value;
function initialize() public initializer {}
function setValue(uint256 _number) public {
_value = _number;
}
function getValue() public view returns (uint256) {
return _value;
}
fallback() external {
_value = 1;
}
}

View File

@@ -0,0 +1,49 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {Initializable} from "../proxy/utils/Initializable.sol";
/**
* @title MigratableMockV1
* @dev This contract is a mock to test initializable functionality through migrations
*/
contract MigratableMockV1 is Initializable {
uint256 public x;
function initialize(uint256 value) public payable initializer {
x = value;
}
}
/**
* @title MigratableMockV2
* @dev This contract is a mock to test migratable functionality with params
*/
contract MigratableMockV2 is MigratableMockV1 {
bool internal _migratedV2;
uint256 public y;
function migrate(uint256 value, uint256 anotherValue) public payable {
require(!_migratedV2);
x = value;
y = anotherValue;
_migratedV2 = true;
}
}
/**
* @title MigratableMockV3
* @dev This contract is a mock to test migratable functionality without params
*/
contract MigratableMockV3 is MigratableMockV2 {
bool internal _migratedV3;
function migrate() public payable {
require(!_migratedV3);
uint256 oldX = x;
x = y;
y = oldX;
_migratedV3 = true;
}
}

View File

@@ -0,0 +1,39 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
// We keep these imports and a dummy contract just to we can run the test suite after transpilation.
import {Address} from "../utils/Address.sol";
import {Arrays} from "../utils/Arrays.sol";
import {AuthorityUtils} from "../access/manager/AuthorityUtils.sol";
import {Base64} from "../utils/Base64.sol";
import {BitMaps} from "../utils/structs/BitMaps.sol";
import {Checkpoints} from "../utils/structs/Checkpoints.sol";
import {CircularBuffer} from "../utils/structs/CircularBuffer.sol";
import {Clones} from "../proxy/Clones.sol";
import {Create2} from "../utils/Create2.sol";
import {DoubleEndedQueue} from "../utils/structs/DoubleEndedQueue.sol";
import {ECDSA} from "../utils/cryptography/ECDSA.sol";
import {EnumerableMap} from "../utils/structs/EnumerableMap.sol";
import {EnumerableSet} from "../utils/structs/EnumerableSet.sol";
import {ERC1155Holder} from "../token/ERC1155/utils/ERC1155Holder.sol";
import {ERC165} from "../utils/introspection/ERC165.sol";
import {ERC165Checker} from "../utils/introspection/ERC165Checker.sol";
import {ERC1967Utils} from "../proxy/ERC1967/ERC1967Utils.sol";
import {ERC721Holder} from "../token/ERC721/utils/ERC721Holder.sol";
import {Math} from "../utils/math/Math.sol";
import {MerkleProof} from "../utils/cryptography/MerkleProof.sol";
import {MessageHashUtils} from "../utils/cryptography/MessageHashUtils.sol";
import {Panic} from "../utils/Panic.sol";
import {Packing} from "../utils/Packing.sol";
import {SafeCast} from "../utils/math/SafeCast.sol";
import {SafeERC20} from "../token/ERC20/utils/SafeERC20.sol";
import {ShortStrings} from "../utils/ShortStrings.sol";
import {SignatureChecker} from "../utils/cryptography/SignatureChecker.sol";
import {SignedMath} from "../utils/math/SignedMath.sol";
import {StorageSlot} from "../utils/StorageSlot.sol";
import {Strings} from "../utils/Strings.sol";
import {Time} from "../utils/types/Time.sol";
contract Dummy1234 {}

View File

@@ -0,0 +1,137 @@
// SPDX-License-Identifier: MIT
// This file was procedurally generated from scripts/generate/templates/StorageSlotMock.js.
pragma solidity ^0.8.24;
import {Multicall} from "../utils/Multicall.sol";
import {StorageSlot} from "../utils/StorageSlot.sol";
contract StorageSlotMock is Multicall {
using StorageSlot for *;
function setAddressSlot(bytes32 slot, address value) public {
slot.getAddressSlot().value = value;
}
function setBooleanSlot(bytes32 slot, bool value) public {
slot.getBooleanSlot().value = value;
}
function setBytes32Slot(bytes32 slot, bytes32 value) public {
slot.getBytes32Slot().value = value;
}
function setUint256Slot(bytes32 slot, uint256 value) public {
slot.getUint256Slot().value = value;
}
function setInt256Slot(bytes32 slot, int256 value) public {
slot.getInt256Slot().value = value;
}
function getAddressSlot(bytes32 slot) public view returns (address) {
return slot.getAddressSlot().value;
}
function getBooleanSlot(bytes32 slot) public view returns (bool) {
return slot.getBooleanSlot().value;
}
function getBytes32Slot(bytes32 slot) public view returns (bytes32) {
return slot.getBytes32Slot().value;
}
function getUint256Slot(bytes32 slot) public view returns (uint256) {
return slot.getUint256Slot().value;
}
function getInt256Slot(bytes32 slot) public view returns (int256) {
return slot.getInt256Slot().value;
}
mapping(uint256 key => string) public stringMap;
function setStringSlot(bytes32 slot, string calldata value) public {
slot.getStringSlot().value = value;
}
function setStringStorage(uint256 key, string calldata value) public {
stringMap[key].getStringSlot().value = value;
}
function getStringSlot(bytes32 slot) public view returns (string memory) {
return slot.getStringSlot().value;
}
function getStringStorage(uint256 key) public view returns (string memory) {
return stringMap[key].getStringSlot().value;
}
mapping(uint256 key => bytes) public bytesMap;
function setBytesSlot(bytes32 slot, bytes calldata value) public {
slot.getBytesSlot().value = value;
}
function setBytesStorage(uint256 key, bytes calldata value) public {
bytesMap[key].getBytesSlot().value = value;
}
function getBytesSlot(bytes32 slot) public view returns (bytes memory) {
return slot.getBytesSlot().value;
}
function getBytesStorage(uint256 key) public view returns (bytes memory) {
return bytesMap[key].getBytesSlot().value;
}
event AddressValue(bytes32 slot, address value);
function tloadAddress(bytes32 slot) public {
emit AddressValue(slot, slot.asAddress().tload());
}
function tstore(bytes32 slot, address value) public {
slot.asAddress().tstore(value);
}
event BooleanValue(bytes32 slot, bool value);
function tloadBoolean(bytes32 slot) public {
emit BooleanValue(slot, slot.asBoolean().tload());
}
function tstore(bytes32 slot, bool value) public {
slot.asBoolean().tstore(value);
}
event Bytes32Value(bytes32 slot, bytes32 value);
function tloadBytes32(bytes32 slot) public {
emit Bytes32Value(slot, slot.asBytes32().tload());
}
function tstore(bytes32 slot, bytes32 value) public {
slot.asBytes32().tstore(value);
}
event Uint256Value(bytes32 slot, uint256 value);
function tloadUint256(bytes32 slot) public {
emit Uint256Value(slot, slot.asUint256().tload());
}
function tstore(bytes32 slot, uint256 value) public {
slot.asUint256().tstore(value);
}
event Int256Value(bytes32 slot, int256 value);
function tloadInt256(bytes32 slot) public {
emit Int256Value(slot, slot.asInt256().tload());
}
function tstore(bytes32 slot, int256 value) public {
slot.asInt256().tstore(value);
}
}

View File

@@ -0,0 +1,26 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {Address} from "../utils/Address.sol";
contract TimelockReentrant {
address private _reenterTarget;
bytes private _reenterData;
bool _reentered;
function disableReentrancy() external {
_reentered = true;
}
function enableRentrancy(address target, bytes calldata data) external {
_reenterTarget = target;
_reenterData = data;
}
function reenter() external {
if (!_reentered) {
_reentered = true;
Address.functionCall(_reenterTarget, _reenterData);
}
}
}

View File

@@ -0,0 +1,27 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {IBeacon} from "../proxy/beacon/IBeacon.sol";
contract UpgradeableBeaconMock is IBeacon {
address public implementation;
constructor(address impl) {
implementation = impl;
}
}
interface IProxyExposed {
// solhint-disable-next-line func-name-mixedcase
function $getBeacon() external view returns (address);
}
contract UpgradeableBeaconReentrantMock is IBeacon {
error BeaconProxyBeaconSlotAddress(address beacon);
function implementation() external view override returns (address) {
// Revert with the beacon seen in the proxy at the moment of calling to check if it's
// set before the call.
revert BeaconProxyBeaconSlotAddress(IProxyExposed(msg.sender).$getBeacon());
}
}

View File

@@ -0,0 +1,42 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {Votes} from "../governance/utils/Votes.sol";
abstract contract VotesMock is Votes {
mapping(address voter => uint256) private _votingUnits;
function getTotalSupply() public view returns (uint256) {
return _getTotalSupply();
}
function delegate(address account, address newDelegation) public {
return _delegate(account, newDelegation);
}
function _getVotingUnits(address account) internal view override returns (uint256) {
return _votingUnits[account];
}
function _mint(address account, uint256 votes) internal {
_votingUnits[account] += votes;
_transferVotingUnits(address(0), account, votes);
}
function _burn(address account, uint256 votes) internal {
_votingUnits[account] += votes;
_transferVotingUnits(account, address(0), votes);
}
}
abstract contract VotesTimestampMock is VotesMock {
function clock() public view override returns (uint48) {
return uint48(block.timestamp);
}
// solhint-disable-next-line func-name-mixedcase
function CLOCK_MODE() public view virtual override returns (string memory) {
return "mode=timestamp";
}
}

View File

@@ -0,0 +1,174 @@
// SPDX-License-Identifier: BSD-3-Clause
// solhint-disable private-vars-leading-underscore
/**
* Copyright 2020 Compound Labs, Inc.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following
* disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote
* products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
pragma solidity ^0.8.20;
contract CompTimelock {
event NewAdmin(address indexed newAdmin);
event NewPendingAdmin(address indexed newPendingAdmin);
event NewDelay(uint256 indexed newDelay);
event CancelTransaction(
bytes32 indexed txHash,
address indexed target,
uint256 value,
string signature,
bytes data,
uint256 eta
);
event ExecuteTransaction(
bytes32 indexed txHash,
address indexed target,
uint256 value,
string signature,
bytes data,
uint256 eta
);
event QueueTransaction(
bytes32 indexed txHash,
address indexed target,
uint256 value,
string signature,
bytes data,
uint256 eta
);
uint256 public constant GRACE_PERIOD = 14 days;
uint256 public constant MINIMUM_DELAY = 2 days;
uint256 public constant MAXIMUM_DELAY = 30 days;
address public admin;
address public pendingAdmin;
uint256 public delay;
mapping(bytes32 => bool) public queuedTransactions;
constructor(address admin_, uint256 delay_) {
require(delay_ >= MINIMUM_DELAY, "Timelock::constructor: Delay must exceed minimum delay.");
require(delay_ <= MAXIMUM_DELAY, "Timelock::setDelay: Delay must not exceed maximum delay.");
admin = admin_;
delay = delay_;
}
receive() external payable {}
function setDelay(uint256 delay_) public {
require(msg.sender == address(this), "Timelock::setDelay: Call must come from Timelock.");
require(delay_ >= MINIMUM_DELAY, "Timelock::setDelay: Delay must exceed minimum delay.");
require(delay_ <= MAXIMUM_DELAY, "Timelock::setDelay: Delay must not exceed maximum delay.");
delay = delay_;
emit NewDelay(delay);
}
function acceptAdmin() public {
require(msg.sender == pendingAdmin, "Timelock::acceptAdmin: Call must come from pendingAdmin.");
admin = msg.sender;
pendingAdmin = address(0);
emit NewAdmin(admin);
}
function setPendingAdmin(address pendingAdmin_) public {
require(msg.sender == address(this), "Timelock::setPendingAdmin: Call must come from Timelock.");
pendingAdmin = pendingAdmin_;
emit NewPendingAdmin(pendingAdmin);
}
function queueTransaction(
address target,
uint256 value,
string memory signature,
bytes memory data,
uint256 eta
) public returns (bytes32) {
require(msg.sender == admin, "Timelock::queueTransaction: Call must come from admin.");
require(
eta >= getBlockTimestamp() + delay,
"Timelock::queueTransaction: Estimated execution block must satisfy delay."
);
bytes32 txHash = keccak256(abi.encode(target, value, signature, data, eta));
queuedTransactions[txHash] = true;
emit QueueTransaction(txHash, target, value, signature, data, eta);
return txHash;
}
function cancelTransaction(
address target,
uint256 value,
string memory signature,
bytes memory data,
uint256 eta
) public {
require(msg.sender == admin, "Timelock::cancelTransaction: Call must come from admin.");
bytes32 txHash = keccak256(abi.encode(target, value, signature, data, eta));
queuedTransactions[txHash] = false;
emit CancelTransaction(txHash, target, value, signature, data, eta);
}
function executeTransaction(
address target,
uint256 value,
string memory signature,
bytes memory data,
uint256 eta
) public payable returns (bytes memory) {
require(msg.sender == admin, "Timelock::executeTransaction: Call must come from admin.");
bytes32 txHash = keccak256(abi.encode(target, value, signature, data, eta));
require(queuedTransactions[txHash], "Timelock::executeTransaction: Transaction hasn't been queued.");
require(getBlockTimestamp() >= eta, "Timelock::executeTransaction: Transaction hasn't surpassed time lock.");
require(getBlockTimestamp() <= eta + GRACE_PERIOD, "Timelock::executeTransaction: Transaction is stale.");
queuedTransactions[txHash] = false;
bytes memory callData;
if (bytes(signature).length == 0) {
callData = data;
} else {
callData = abi.encodePacked(bytes4(keccak256(bytes(signature))), data);
}
// solium-disable-next-line security/no-call-value
(bool success, bytes memory returnData) = target.call{value: value}(callData);
require(success, "Timelock::executeTransaction: Transaction execution reverted.");
emit ExecuteTransaction(txHash, target, value, signature, data, eta);
return returnData;
}
function getBlockTimestamp() internal view returns (uint256) {
// solium-disable-next-line security/no-block-members
return block.timestamp;
}
}

View File

@@ -0,0 +1,22 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {ERC20} from "../../token/ERC20/ERC20.sol";
contract ERC20WithAutoMinerReward is ERC20 {
constructor() ERC20("Reward", "RWD") {
_mintMinerReward();
}
function _mintMinerReward() internal {
_mint(block.coinbase, 1000);
}
function _update(address from, address to, uint256 value) internal virtual override {
if (!(from == address(0) && to == block.coinbase)) {
_mintMinerReward();
}
super._update(from, to, value);
}
}

View File

@@ -0,0 +1,103 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {IERC20} from "../../token/ERC20/IERC20.sol";
import {ERC4626} from "../../token/ERC20/extensions/ERC4626.sol";
import {SafeERC20} from "../../token/ERC20/utils/SafeERC20.sol";
import {Math} from "../../utils/math/Math.sol";
/// @dev ERC-4626 vault with entry/exit fees expressed in https://en.wikipedia.org/wiki/Basis_point[basis point (bp)].
abstract contract ERC4626Fees is ERC4626 {
using Math for uint256;
uint256 private constant _BASIS_POINT_SCALE = 1e4;
// === Overrides ===
/// @dev Preview taking an entry fee on deposit. See {IERC4626-previewDeposit}.
function previewDeposit(uint256 assets) public view virtual override returns (uint256) {
uint256 fee = _feeOnTotal(assets, _entryFeeBasisPoints());
return super.previewDeposit(assets - fee);
}
/// @dev Preview adding an entry fee on mint. See {IERC4626-previewMint}.
function previewMint(uint256 shares) public view virtual override returns (uint256) {
uint256 assets = super.previewMint(shares);
return assets + _feeOnRaw(assets, _entryFeeBasisPoints());
}
/// @dev Preview adding an exit fee on withdraw. See {IERC4626-previewWithdraw}.
function previewWithdraw(uint256 assets) public view virtual override returns (uint256) {
uint256 fee = _feeOnRaw(assets, _exitFeeBasisPoints());
return super.previewWithdraw(assets + fee);
}
/// @dev Preview taking an exit fee on redeem. See {IERC4626-previewRedeem}.
function previewRedeem(uint256 shares) public view virtual override returns (uint256) {
uint256 assets = super.previewRedeem(shares);
return assets - _feeOnTotal(assets, _exitFeeBasisPoints());
}
/// @dev Send entry fee to {_entryFeeRecipient}. See {IERC4626-_deposit}.
function _deposit(address caller, address receiver, uint256 assets, uint256 shares) internal virtual override {
uint256 fee = _feeOnTotal(assets, _entryFeeBasisPoints());
address recipient = _entryFeeRecipient();
super._deposit(caller, receiver, assets, shares);
if (fee > 0 && recipient != address(this)) {
SafeERC20.safeTransfer(IERC20(asset()), recipient, fee);
}
}
/// @dev Send exit fee to {_exitFeeRecipient}. See {IERC4626-_deposit}.
function _withdraw(
address caller,
address receiver,
address owner,
uint256 assets,
uint256 shares
) internal virtual override {
uint256 fee = _feeOnRaw(assets, _exitFeeBasisPoints());
address recipient = _exitFeeRecipient();
super._withdraw(caller, receiver, owner, assets, shares);
if (fee > 0 && recipient != address(this)) {
SafeERC20.safeTransfer(IERC20(asset()), recipient, fee);
}
}
// === Fee configuration ===
function _entryFeeBasisPoints() internal view virtual returns (uint256) {
return 0; // replace with e.g. 100 for 1%
}
function _exitFeeBasisPoints() internal view virtual returns (uint256) {
return 0; // replace with e.g. 100 for 1%
}
function _entryFeeRecipient() internal view virtual returns (address) {
return address(0); // replace with e.g. a treasury address
}
function _exitFeeRecipient() internal view virtual returns (address) {
return address(0); // replace with e.g. a treasury address
}
// === Fee operations ===
/// @dev Calculates the fees that should be added to an amount `assets` that does not already include fees.
/// Used in {IERC4626-mint} and {IERC4626-withdraw} operations.
function _feeOnRaw(uint256 assets, uint256 feeBasisPoints) private pure returns (uint256) {
return assets.mulDiv(feeBasisPoints, _BASIS_POINT_SCALE, Math.Rounding.Ceil);
}
/// @dev Calculates the fee part of an amount `assets` that already includes fees.
/// Used in {IERC4626-deposit} and {IERC4626-redeem} operations.
function _feeOnTotal(uint256 assets, uint256 feeBasisPoints) private pure returns (uint256) {
return assets.mulDiv(feeBasisPoints, feeBasisPoints + _BASIS_POINT_SCALE, Math.Rounding.Ceil);
}
}

View File

@@ -0,0 +1,9 @@
// contracts/MyNFT.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {ERC721} from "../../token/ERC721/ERC721.sol";
contract MyNFT is ERC721 {
constructor() ERC721("MyNFT", "MNFT") {}
}

View File

@@ -0,0 +1,25 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {AccessControl} from "../../../access/AccessControl.sol";
import {ERC20} from "../../../token/ERC20/ERC20.sol";
contract AccessControlERC20MintBase is ERC20, AccessControl {
// Create a new role identifier for the minter role
bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
error CallerNotMinter(address caller);
constructor(address minter) ERC20("MyToken", "TKN") {
// Grant the minter role to a specified account
_grantRole(MINTER_ROLE, minter);
}
function mint(address to, uint256 amount) public {
// Check that the calling account has the minter role
if (!hasRole(MINTER_ROLE, msg.sender)) {
revert CallerNotMinter(msg.sender);
}
_mint(to, amount);
}
}

View File

@@ -0,0 +1,24 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {AccessControl} from "../../../access/AccessControl.sol";
import {ERC20} from "../../../token/ERC20/ERC20.sol";
contract AccessControlERC20MintMissing is ERC20, AccessControl {
bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
bytes32 public constant BURNER_ROLE = keccak256("BURNER_ROLE");
constructor() ERC20("MyToken", "TKN") {
// Grant the contract deployer the default admin role: it will be able
// to grant and revoke any roles
_grantRole(DEFAULT_ADMIN_ROLE, msg.sender);
}
function mint(address to, uint256 amount) public onlyRole(MINTER_ROLE) {
_mint(to, amount);
}
function burn(address from, uint256 amount) public onlyRole(BURNER_ROLE) {
_burn(from, amount);
}
}

View File

@@ -0,0 +1,23 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {AccessControl} from "../../../access/AccessControl.sol";
import {ERC20} from "../../../token/ERC20/ERC20.sol";
contract AccessControlERC20Mint is ERC20, AccessControl {
bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
bytes32 public constant BURNER_ROLE = keccak256("BURNER_ROLE");
constructor(address minter, address burner) ERC20("MyToken", "TKN") {
_grantRole(MINTER_ROLE, minter);
_grantRole(BURNER_ROLE, burner);
}
function mint(address to, uint256 amount) public onlyRole(MINTER_ROLE) {
_mint(to, amount);
}
function burn(address from, uint256 amount) public onlyRole(BURNER_ROLE) {
_burn(from, amount);
}
}

View File

@@ -0,0 +1,14 @@
// contracts/AccessControlModified.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {AccessControl} from "../../../access/AccessControl.sol";
contract AccessControlModified is AccessControl {
error AccessControlNonRevokable();
// Override the revokeRole function
function revokeRole(bytes32, address) public pure override {
revert AccessControlNonRevokable();
}
}

View File

@@ -0,0 +1,17 @@
// contracts/AccessControlNonRevokableAdmin.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {AccessControl} from "../../../access/AccessControl.sol";
contract AccessControlNonRevokableAdmin is AccessControl {
error AccessControlNonRevokable();
function revokeRole(bytes32 role, address account) public override {
if (role == DEFAULT_ADMIN_ROLE) {
revert AccessControlNonRevokable();
}
super.revokeRole(role, account);
}
}

View File

@@ -0,0 +1,16 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {AccessManaged} from "../../../access/manager/AccessManaged.sol";
import {ERC20} from "../../../token/ERC20/ERC20.sol";
contract AccessManagedERC20Mint is ERC20, AccessManaged {
constructor(address manager) ERC20("MyToken", "TKN") AccessManaged(manager) {}
// Minting is restricted according to the manager rules for this function.
// The function is identified by its selector: 0x40c10f19.
// Calculated with bytes4(keccak256('mint(address,uint256)'))
function mint(address to, uint256 amount) public restricted {
_mint(to, amount);
}
}

View File

@@ -0,0 +1,17 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {Ownable} from "../../../access/Ownable.sol";
contract MyContract is Ownable {
constructor(address initialOwner) Ownable(initialOwner) {}
function normalThing() public {
// anyone can call this normalThing()
}
function specialThing() public onlyOwner {
// only the owner can call specialThing()!
}
}

View File

@@ -0,0 +1,81 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {IGovernor, Governor} from "../../../governance/Governor.sol";
import {GovernorCountingSimple} from "../../../governance/extensions/GovernorCountingSimple.sol";
import {GovernorVotes} from "../../../governance/extensions/GovernorVotes.sol";
import {GovernorVotesQuorumFraction} from "../../../governance/extensions/GovernorVotesQuorumFraction.sol";
import {GovernorTimelockControl} from "../../../governance/extensions/GovernorTimelockControl.sol";
import {TimelockController} from "../../../governance/TimelockController.sol";
import {IVotes} from "../../../governance/utils/IVotes.sol";
import {IERC165} from "../../../interfaces/IERC165.sol";
contract MyGovernor is
Governor,
GovernorCountingSimple,
GovernorVotes,
GovernorVotesQuorumFraction,
GovernorTimelockControl
{
constructor(
IVotes _token,
TimelockController _timelock
) Governor("MyGovernor") GovernorVotes(_token) GovernorVotesQuorumFraction(4) GovernorTimelockControl(_timelock) {}
function votingDelay() public pure override returns (uint256) {
return 7200; // 1 day
}
function votingPeriod() public pure override returns (uint256) {
return 50400; // 1 week
}
function proposalThreshold() public pure override returns (uint256) {
return 0;
}
// The functions below are overrides required by Solidity.
function state(uint256 proposalId) public view override(Governor, GovernorTimelockControl) returns (ProposalState) {
return super.state(proposalId);
}
function proposalNeedsQueuing(
uint256 proposalId
) public view virtual override(Governor, GovernorTimelockControl) returns (bool) {
return super.proposalNeedsQueuing(proposalId);
}
function _queueOperations(
uint256 proposalId,
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 descriptionHash
) internal override(Governor, GovernorTimelockControl) returns (uint48) {
return super._queueOperations(proposalId, targets, values, calldatas, descriptionHash);
}
function _executeOperations(
uint256 proposalId,
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 descriptionHash
) internal override(Governor, GovernorTimelockControl) {
super._executeOperations(proposalId, targets, values, calldatas, descriptionHash);
}
function _cancel(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 descriptionHash
) internal override(Governor, GovernorTimelockControl) returns (uint256) {
return super._cancel(targets, values, calldatas, descriptionHash);
}
function _executor() internal view override(Governor, GovernorTimelockControl) returns (address) {
return super._executor();
}
}

View File

@@ -0,0 +1,21 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {ERC20} from "../../../token/ERC20/ERC20.sol";
import {ERC20Permit} from "../../../token/ERC20/extensions/ERC20Permit.sol";
import {ERC20Votes} from "../../../token/ERC20/extensions/ERC20Votes.sol";
import {Nonces} from "../../../utils/Nonces.sol";
contract MyToken is ERC20, ERC20Permit, ERC20Votes {
constructor() ERC20("MyToken", "MTK") ERC20Permit("MyToken") {}
// The functions below are overrides required by Solidity.
function _update(address from, address to, uint256 amount) internal override(ERC20, ERC20Votes) {
super._update(from, to, amount);
}
function nonces(address owner) public view virtual override(ERC20Permit, Nonces) returns (uint256) {
return super.nonces(owner);
}
}

View File

@@ -0,0 +1,32 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {ERC20} from "../../../token/ERC20/ERC20.sol";
import {ERC20Permit} from "../../../token/ERC20/extensions/ERC20Permit.sol";
import {ERC20Votes} from "../../../token/ERC20/extensions/ERC20Votes.sol";
import {Nonces} from "../../../utils/Nonces.sol";
contract MyTokenTimestampBased is ERC20, ERC20Permit, ERC20Votes {
constructor() ERC20("MyTokenTimestampBased", "MTK") ERC20Permit("MyTokenTimestampBased") {}
// Overrides IERC6372 functions to make the token & governor timestamp-based
function clock() public view override returns (uint48) {
return uint48(block.timestamp);
}
// solhint-disable-next-line func-name-mixedcase
function CLOCK_MODE() public pure override returns (string memory) {
return "mode=timestamp";
}
// The functions below are overrides required by Solidity.
function _update(address from, address to, uint256 amount) internal override(ERC20, ERC20Votes) {
super._update(from, to, amount);
}
function nonces(address owner) public view virtual override(ERC20Permit, Nonces) returns (uint256) {
return super.nonces(owner);
}
}

View File

@@ -0,0 +1,28 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {IERC20, ERC20} from "../../../token/ERC20/ERC20.sol";
import {ERC20Permit} from "../../../token/ERC20/extensions/ERC20Permit.sol";
import {ERC20Votes} from "../../../token/ERC20/extensions/ERC20Votes.sol";
import {ERC20Wrapper} from "../../../token/ERC20/extensions/ERC20Wrapper.sol";
import {Nonces} from "../../../utils/Nonces.sol";
contract MyTokenWrapped is ERC20, ERC20Permit, ERC20Votes, ERC20Wrapper {
constructor(
IERC20 wrappedToken
) ERC20("MyTokenWrapped", "MTK") ERC20Permit("MyTokenWrapped") ERC20Wrapper(wrappedToken) {}
// The functions below are overrides required by Solidity.
function decimals() public view override(ERC20, ERC20Wrapper) returns (uint8) {
return super.decimals();
}
function _update(address from, address to, uint256 amount) internal override(ERC20, ERC20Votes) {
super._update(from, to, amount);
}
function nonces(address owner) public view virtual override(ERC20Permit, Nonces) returns (uint256) {
return super.nonces(owner);
}
}

View File

@@ -0,0 +1,21 @@
// contracts/GameItems.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {ERC1155} from "../../../../token/ERC1155/ERC1155.sol";
contract GameItems is ERC1155 {
uint256 public constant GOLD = 0;
uint256 public constant SILVER = 1;
uint256 public constant THORS_HAMMER = 2;
uint256 public constant SWORD = 3;
uint256 public constant SHIELD = 4;
constructor() ERC1155("https://game.example/api/item/{id}.json") {
_mint(msg.sender, GOLD, 10 ** 18, "");
_mint(msg.sender, SILVER, 10 ** 27, "");
_mint(msg.sender, THORS_HAMMER, 1, "");
_mint(msg.sender, SWORD, 10 ** 9, "");
_mint(msg.sender, SHIELD, 10 ** 9, "");
}
}

View File

@@ -0,0 +1,7 @@
// contracts/MyERC115HolderContract.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {ERC1155Holder} from "../../../../token/ERC1155/utils/ERC1155Holder.sol";
contract MyERC115HolderContract is ERC1155Holder {}

View File

@@ -0,0 +1,11 @@
// contracts/GLDToken.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {ERC20} from "../../../../token/ERC20/ERC20.sol";
contract GLDToken is ERC20 {
constructor(uint256 initialSupply) ERC20("Gold", "GLD") {
_mint(msg.sender, initialSupply);
}
}

View File

@@ -0,0 +1,19 @@
// contracts/GameItem.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {ERC721URIStorage, ERC721} from "../../../../token/ERC721/extensions/ERC721URIStorage.sol";
contract GameItem is ERC721URIStorage {
uint256 private _nextTokenId;
constructor() ERC721("GameItem", "ITM") {}
function awardItem(address player, string memory tokenURI) public returns (uint256) {
uint256 tokenId = _nextTokenId++;
_mint(player, tokenId);
_setTokenURI(tokenId, tokenURI);
return tokenId;
}
}

View File

@@ -0,0 +1,27 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {ERC721} from "../../../token/ERC721/ERC721.sol";
import {Strings} from "../../../utils/Strings.sol";
import {Base64} from "../../../utils/Base64.sol";
contract Base64NFT is ERC721 {
using Strings for uint256;
constructor() ERC721("Base64NFT", "MTK") {}
// ...
function tokenURI(uint256 tokenId) public pure override returns (string memory) {
// Equivalent to:
// {
// "name": "Base64NFT #1",
// // Replace with extra ERC-721 Metadata properties
// }
// prettier-ignore
string memory dataURI = string.concat("{\"name\": \"Base64NFT #", tokenId.toString(), "\"}");
return string.concat("data:application/json;base64,", Base64.encode(bytes(dataURI)));
}
}

View File

@@ -0,0 +1,15 @@
// contracts/Box.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {Multicall} from "../../../utils/Multicall.sol";
contract Box is Multicall {
function foo() public {
// ...
}
function bar() public {
// ...
}
}

View File

@@ -0,0 +1,14 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {Governor} from "../../governance/Governor.sol";
import {GovernorSettings} from "../../governance/extensions/GovernorSettings.sol";
import {GovernorCountingSimple} from "../../governance/extensions/GovernorCountingSimple.sol";
import {GovernorVotesQuorumFraction} from "../../governance/extensions/GovernorVotesQuorumFraction.sol";
abstract contract GovernorMock is GovernorSettings, GovernorVotesQuorumFraction, GovernorCountingSimple {
function proposalThreshold() public view override(Governor, GovernorSettings) returns (uint256) {
return super.proposalThreshold();
}
}

View File

@@ -0,0 +1,46 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {Governor} from "../../governance/Governor.sol";
import {GovernorPreventLateQuorum} from "../../governance/extensions/GovernorPreventLateQuorum.sol";
import {GovernorSettings} from "../../governance/extensions/GovernorSettings.sol";
import {GovernorCountingSimple} from "../../governance/extensions/GovernorCountingSimple.sol";
import {GovernorVotes} from "../../governance/extensions/GovernorVotes.sol";
abstract contract GovernorPreventLateQuorumMock is
GovernorSettings,
GovernorVotes,
GovernorCountingSimple,
GovernorPreventLateQuorum
{
uint256 private _quorum;
constructor(uint256 quorum_) {
_quorum = quorum_;
}
function quorum(uint256) public view override returns (uint256) {
return _quorum;
}
function proposalDeadline(
uint256 proposalId
) public view override(Governor, GovernorPreventLateQuorum) returns (uint256) {
return super.proposalDeadline(proposalId);
}
function proposalThreshold() public view override(Governor, GovernorSettings) returns (uint256) {
return super.proposalThreshold();
}
function _castVote(
uint256 proposalId,
address account,
uint8 support,
string memory reason,
bytes memory params
) internal override(Governor, GovernorPreventLateQuorum) returns (uint256) {
return super._castVote(proposalId, account, support, reason, params);
}
}

View File

@@ -0,0 +1,79 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;
import {IGovernor, Governor} from "../../governance/Governor.sol";
import {GovernorTimelockControl} from "../../governance/extensions/GovernorTimelockControl.sol";
import {GovernorSettings} from "../../governance/extensions/GovernorSettings.sol";
import {GovernorCountingSimple} from "../../governance/extensions/GovernorCountingSimple.sol";
import {GovernorVotesQuorumFraction} from "../../governance/extensions/GovernorVotesQuorumFraction.sol";
import {GovernorStorage} from "../../governance/extensions/GovernorStorage.sol";
abstract contract GovernorStorageMock is
GovernorSettings,
GovernorTimelockControl,
GovernorVotesQuorumFraction,
GovernorCountingSimple,
GovernorStorage
{
function quorum(uint256 blockNumber) public view override(Governor, GovernorVotesQuorumFraction) returns (uint256) {
return super.quorum(blockNumber);
}
function state(uint256 proposalId) public view override(Governor, GovernorTimelockControl) returns (ProposalState) {
return super.state(proposalId);
}
function proposalThreshold() public view override(Governor, GovernorSettings) returns (uint256) {
return super.proposalThreshold();
}
function proposalNeedsQueuing(
uint256 proposalId
) public view virtual override(Governor, GovernorTimelockControl) returns (bool) {
return super.proposalNeedsQueuing(proposalId);
}
function _propose(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
string memory description,
address proposer
) internal virtual override(Governor, GovernorStorage) returns (uint256) {
return super._propose(targets, values, calldatas, description, proposer);
}
function _queueOperations(
uint256 proposalId,
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 descriptionHash
) internal override(Governor, GovernorTimelockControl) returns (uint48) {
return super._queueOperations(proposalId, targets, values, calldatas, descriptionHash);
}
function _executeOperations(
uint256 proposalId,
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 descriptionHash
) internal override(Governor, GovernorTimelockControl) {
super._executeOperations(proposalId, targets, values, calldatas, descriptionHash);
}
function _cancel(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 descriptionHash
) internal override(Governor, GovernorTimelockControl) returns (uint256) {
return super._cancel(targets, values, calldatas, descriptionHash);
}
function _executor() internal view override(Governor, GovernorTimelockControl) returns (address) {
return super._executor();
}
}

View File

@@ -0,0 +1,70 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {IGovernor, Governor} from "../../governance/Governor.sol";
import {GovernorTimelockAccess} from "../../governance/extensions/GovernorTimelockAccess.sol";
import {GovernorSettings} from "../../governance/extensions/GovernorSettings.sol";
import {GovernorCountingSimple} from "../../governance/extensions/GovernorCountingSimple.sol";
import {GovernorVotesQuorumFraction} from "../../governance/extensions/GovernorVotesQuorumFraction.sol";
abstract contract GovernorTimelockAccessMock is
GovernorSettings,
GovernorTimelockAccess,
GovernorVotesQuorumFraction,
GovernorCountingSimple
{
function nonGovernanceFunction() external {}
function quorum(uint256 blockNumber) public view override(Governor, GovernorVotesQuorumFraction) returns (uint256) {
return super.quorum(blockNumber);
}
function proposalThreshold() public view override(Governor, GovernorSettings) returns (uint256) {
return super.proposalThreshold();
}
function proposalNeedsQueuing(
uint256 proposalId
) public view virtual override(Governor, GovernorTimelockAccess) returns (bool) {
return super.proposalNeedsQueuing(proposalId);
}
function propose(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
string memory description
) public override(Governor, GovernorTimelockAccess) returns (uint256) {
return super.propose(targets, values, calldatas, description);
}
function _queueOperations(
uint256 proposalId,
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 descriptionHash
) internal override(Governor, GovernorTimelockAccess) returns (uint48) {
return super._queueOperations(proposalId, targets, values, calldatas, descriptionHash);
}
function _executeOperations(
uint256 proposalId,
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 descriptionHash
) internal override(Governor, GovernorTimelockAccess) {
super._executeOperations(proposalId, targets, values, calldatas, descriptionHash);
}
function _cancel(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 descriptionHash
) internal override(Governor, GovernorTimelockAccess) returns (uint256) {
return super._cancel(targets, values, calldatas, descriptionHash);
}
}

View File

@@ -0,0 +1,69 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {IGovernor, Governor} from "../../governance/Governor.sol";
import {GovernorTimelockCompound} from "../../governance/extensions/GovernorTimelockCompound.sol";
import {GovernorSettings} from "../../governance/extensions/GovernorSettings.sol";
import {GovernorCountingSimple} from "../../governance/extensions/GovernorCountingSimple.sol";
import {GovernorVotesQuorumFraction} from "../../governance/extensions/GovernorVotesQuorumFraction.sol";
abstract contract GovernorTimelockCompoundMock is
GovernorSettings,
GovernorTimelockCompound,
GovernorVotesQuorumFraction,
GovernorCountingSimple
{
function quorum(uint256 blockNumber) public view override(Governor, GovernorVotesQuorumFraction) returns (uint256) {
return super.quorum(blockNumber);
}
function state(
uint256 proposalId
) public view override(Governor, GovernorTimelockCompound) returns (ProposalState) {
return super.state(proposalId);
}
function proposalThreshold() public view override(Governor, GovernorSettings) returns (uint256) {
return super.proposalThreshold();
}
function proposalNeedsQueuing(
uint256 proposalId
) public view virtual override(Governor, GovernorTimelockCompound) returns (bool) {
return super.proposalNeedsQueuing(proposalId);
}
function _queueOperations(
uint256 proposalId,
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 descriptionHash
) internal override(Governor, GovernorTimelockCompound) returns (uint48) {
return super._queueOperations(proposalId, targets, values, calldatas, descriptionHash);
}
function _executeOperations(
uint256 proposalId,
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 descriptionHash
) internal override(Governor, GovernorTimelockCompound) {
super._executeOperations(proposalId, targets, values, calldatas, descriptionHash);
}
function _cancel(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 descriptionHash
) internal override(Governor, GovernorTimelockCompound) returns (uint256) {
return super._cancel(targets, values, calldatas, descriptionHash);
}
function _executor() internal view override(Governor, GovernorTimelockCompound) returns (address) {
return super._executor();
}
}

View File

@@ -0,0 +1,69 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {IGovernor, Governor} from "../../governance/Governor.sol";
import {GovernorTimelockControl} from "../../governance/extensions/GovernorTimelockControl.sol";
import {GovernorSettings} from "../../governance/extensions/GovernorSettings.sol";
import {GovernorCountingSimple} from "../../governance/extensions/GovernorCountingSimple.sol";
import {GovernorVotesQuorumFraction} from "../../governance/extensions/GovernorVotesQuorumFraction.sol";
abstract contract GovernorTimelockControlMock is
GovernorSettings,
GovernorTimelockControl,
GovernorVotesQuorumFraction,
GovernorCountingSimple
{
function quorum(uint256 blockNumber) public view override(Governor, GovernorVotesQuorumFraction) returns (uint256) {
return super.quorum(blockNumber);
}
function state(uint256 proposalId) public view override(Governor, GovernorTimelockControl) returns (ProposalState) {
return super.state(proposalId);
}
function proposalThreshold() public view override(Governor, GovernorSettings) returns (uint256) {
return super.proposalThreshold();
}
function proposalNeedsQueuing(
uint256 proposalId
) public view virtual override(Governor, GovernorTimelockControl) returns (bool) {
return super.proposalNeedsQueuing(proposalId);
}
function _queueOperations(
uint256 proposalId,
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 descriptionHash
) internal override(Governor, GovernorTimelockControl) returns (uint48) {
return super._queueOperations(proposalId, targets, values, calldatas, descriptionHash);
}
function _executeOperations(
uint256 proposalId,
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 descriptionHash
) internal override(Governor, GovernorTimelockControl) {
super._executeOperations(proposalId, targets, values, calldatas, descriptionHash);
}
function _cancel(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 descriptionHash
) internal override(Governor, GovernorTimelockControl) returns (uint256) {
return super._cancel(targets, values, calldatas, descriptionHash);
}
function _executor() internal view override(Governor, GovernorTimelockControl) returns (address) {
return super._executor();
}
function nonGovernanceFunction() external {}
}

View File

@@ -0,0 +1,20 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {GovernorCountingSimple} from "../../governance/extensions/GovernorCountingSimple.sol";
import {GovernorVotes} from "../../governance/extensions/GovernorVotes.sol";
abstract contract GovernorVoteMocks is GovernorVotes, GovernorCountingSimple {
function quorum(uint256) public pure override returns (uint256) {
return 0;
}
function votingDelay() public pure override returns (uint256) {
return 4;
}
function votingPeriod() public pure override returns (uint256) {
return 16;
}
}

View File

@@ -0,0 +1,51 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {Governor} from "../../governance/Governor.sol";
import {GovernorCountingSimple} from "../../governance/extensions/GovernorCountingSimple.sol";
import {GovernorVotes} from "../../governance/extensions/GovernorVotes.sol";
abstract contract GovernorWithParamsMock is GovernorVotes, GovernorCountingSimple {
event CountParams(uint256 uintParam, string strParam);
function quorum(uint256) public pure override returns (uint256) {
return 0;
}
function votingDelay() public pure override returns (uint256) {
return 4;
}
function votingPeriod() public pure override returns (uint256) {
return 16;
}
function _getVotes(
address account,
uint256 blockNumber,
bytes memory params
) internal view override(Governor, GovernorVotes) returns (uint256) {
uint256 reduction = 0;
// If the user provides parameters, we reduce the voting weight by the amount of the integer param
if (params.length > 0) {
(reduction, ) = abi.decode(params, (uint256, string));
}
// reverts on overflow
return super._getVotes(account, blockNumber, params) - reduction;
}
function _countVote(
uint256 proposalId,
address account,
uint8 support,
uint256 weight,
bytes memory params
) internal override(Governor, GovernorCountingSimple) {
if (params.length > 0) {
(uint256 _uintParam, string memory _strParam) = abi.decode(params, (uint256, string));
emit CountParams(_uintParam, _strParam);
}
return super._countVote(proposalId, account, support, weight, params);
}
}

View File

@@ -0,0 +1,11 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
contract BadBeaconNoImpl {}
contract BadBeaconNotContract {
function implementation() external pure returns (address) {
return address(0x1);
}
}

View File

@@ -0,0 +1,19 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
/**
* @dev Implementation contract with a payable changeAdmin(address) function made to clash with
* TransparentUpgradeableProxy's to test correct functioning of the Transparent Proxy feature.
*/
contract ClashingImplementation {
event ClashingImplementationCall();
function upgradeToAndCall(address, bytes calldata) external payable {
emit ClashingImplementationCall();
}
function delegatedFunction() external pure returns (bool) {
return true;
}
}

View File

@@ -0,0 +1,35 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {UUPSUpgradeable} from "../../proxy/utils/UUPSUpgradeable.sol";
import {ERC1967Utils} from "../../proxy/ERC1967/ERC1967Utils.sol";
contract NonUpgradeableMock {
uint256 internal _counter;
function current() external view returns (uint256) {
return _counter;
}
function increment() external {
++_counter;
}
}
contract UUPSUpgradeableMock is NonUpgradeableMock, UUPSUpgradeable {
// Not having any checks in this function is dangerous! Do not do this outside tests!
function _authorizeUpgrade(address) internal override {}
}
contract UUPSUpgradeableUnsafeMock is UUPSUpgradeableMock {
function upgradeToAndCall(address newImplementation, bytes memory data) public payable override {
ERC1967Utils.upgradeToAndCall(newImplementation, data);
}
}
contract UUPSUnsupportedProxiableUUID is UUPSUpgradeableMock {
function proxiableUUID() external pure override returns (bytes32) {
return keccak256("invalid UUID");
}
}

View File

@@ -0,0 +1,74 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {IERC1155Receiver} from "../../token/ERC1155/IERC1155Receiver.sol";
import {ERC165} from "../../utils/introspection/ERC165.sol";
contract ERC1155ReceiverMock is ERC165, IERC1155Receiver {
enum RevertType {
None,
RevertWithoutMessage,
RevertWithMessage,
RevertWithCustomError,
Panic
}
bytes4 private immutable _recRetval;
bytes4 private immutable _batRetval;
RevertType private immutable _error;
event Received(address operator, address from, uint256 id, uint256 value, bytes data, uint256 gas);
event BatchReceived(address operator, address from, uint256[] ids, uint256[] values, bytes data, uint256 gas);
error CustomError(bytes4);
constructor(bytes4 recRetval, bytes4 batRetval, RevertType error) {
_recRetval = recRetval;
_batRetval = batRetval;
_error = error;
}
function onERC1155Received(
address operator,
address from,
uint256 id,
uint256 value,
bytes calldata data
) external returns (bytes4) {
if (_error == RevertType.RevertWithoutMessage) {
revert();
} else if (_error == RevertType.RevertWithMessage) {
revert("ERC1155ReceiverMock: reverting on receive");
} else if (_error == RevertType.RevertWithCustomError) {
revert CustomError(_recRetval);
} else if (_error == RevertType.Panic) {
uint256 a = uint256(0) / uint256(0);
a;
}
emit Received(operator, from, id, value, data, gasleft());
return _recRetval;
}
function onERC1155BatchReceived(
address operator,
address from,
uint256[] calldata ids,
uint256[] calldata values,
bytes calldata data
) external returns (bytes4) {
if (_error == RevertType.RevertWithoutMessage) {
revert();
} else if (_error == RevertType.RevertWithMessage) {
revert("ERC1155ReceiverMock: reverting on batch receive");
} else if (_error == RevertType.RevertWithCustomError) {
revert CustomError(_recRetval);
} else if (_error == RevertType.Panic) {
uint256 a = uint256(0) / uint256(0);
a;
}
emit BatchReceived(operator, from, ids, values, data, gasleft());
return _batRetval;
}
}

View File

@@ -0,0 +1,14 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {IERC20} from "../../interfaces/IERC20.sol";
import {ERC20, ERC1363} from "../../token/ERC20/extensions/ERC1363.sol";
// contract that replicate USDT approval behavior in approveAndCall
abstract contract ERC1363ForceApproveMock is ERC1363 {
function approveAndCall(address spender, uint256 amount, bytes memory data) public virtual override returns (bool) {
require(amount == 0 || allowance(msg.sender, spender) == 0, "USDT approval failure");
return super.approveAndCall(spender, amount, data);
}
}

View File

@@ -0,0 +1,34 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {IERC20, ERC20} from "../../token/ERC20/ERC20.sol";
import {ERC1363} from "../../token/ERC20/extensions/ERC1363.sol";
abstract contract ERC1363NoReturnMock is ERC1363 {
function transferAndCall(address to, uint256 value, bytes memory data) public override returns (bool) {
super.transferAndCall(to, value, data);
assembly {
return(0, 0)
}
}
function transferFromAndCall(
address from,
address to,
uint256 value,
bytes memory data
) public override returns (bool) {
super.transferFromAndCall(from, to, value, data);
assembly {
return(0, 0)
}
}
function approveAndCall(address spender, uint256 value, bytes memory data) public override returns (bool) {
super.approveAndCall(spender, value, data);
assembly {
return(0, 0)
}
}
}

View File

@@ -0,0 +1,52 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {IERC1363Receiver} from "../../interfaces/IERC1363Receiver.sol";
contract ERC1363ReceiverMock is IERC1363Receiver {
enum RevertType {
None,
RevertWithoutMessage,
RevertWithMessage,
RevertWithCustomError,
Panic
}
bytes4 private _retval;
RevertType private _error;
event Received(address operator, address from, uint256 value, bytes data);
error CustomError(bytes4);
constructor() {
_retval = IERC1363Receiver.onTransferReceived.selector;
_error = RevertType.None;
}
function setUp(bytes4 retval, RevertType error) public {
_retval = retval;
_error = error;
}
function onTransferReceived(
address operator,
address from,
uint256 value,
bytes calldata data
) external override returns (bytes4) {
if (_error == RevertType.RevertWithoutMessage) {
revert();
} else if (_error == RevertType.RevertWithMessage) {
revert("ERC1363ReceiverMock: reverting");
} else if (_error == RevertType.RevertWithCustomError) {
revert CustomError(_retval);
} else if (_error == RevertType.Panic) {
uint256 a = uint256(0) / uint256(0);
a;
}
emit Received(operator, from, value, data);
return _retval;
}
}

View File

@@ -0,0 +1,34 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {IERC20, ERC20} from "../../token/ERC20/ERC20.sol";
import {ERC1363} from "../../token/ERC20/extensions/ERC1363.sol";
abstract contract ERC1363ReturnFalseOnERC20Mock is ERC1363 {
function transfer(address, uint256) public pure override(IERC20, ERC20) returns (bool) {
return false;
}
function transferFrom(address, address, uint256) public pure override(IERC20, ERC20) returns (bool) {
return false;
}
function approve(address, uint256) public pure override(IERC20, ERC20) returns (bool) {
return false;
}
}
abstract contract ERC1363ReturnFalseMock is ERC1363 {
function transferAndCall(address, uint256, bytes memory) public pure override returns (bool) {
return false;
}
function transferFromAndCall(address, address, uint256, bytes memory) public pure override returns (bool) {
return false;
}
function approveAndCall(address, uint256, bytes memory) public pure override returns (bool) {
return false;
}
}

View File

@@ -0,0 +1,47 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {IERC1363Spender} from "../../interfaces/IERC1363Spender.sol";
contract ERC1363SpenderMock is IERC1363Spender {
enum RevertType {
None,
RevertWithoutMessage,
RevertWithMessage,
RevertWithCustomError,
Panic
}
bytes4 private _retval;
RevertType private _error;
event Approved(address owner, uint256 value, bytes data);
error CustomError(bytes4);
constructor() {
_retval = IERC1363Spender.onApprovalReceived.selector;
_error = RevertType.None;
}
function setUp(bytes4 retval, RevertType error) public {
_retval = retval;
_error = error;
}
function onApprovalReceived(address owner, uint256 value, bytes calldata data) external override returns (bytes4) {
if (_error == RevertType.RevertWithoutMessage) {
revert();
} else if (_error == RevertType.RevertWithMessage) {
revert("ERC1363SpenderMock: reverting");
} else if (_error == RevertType.RevertWithCustomError) {
revert CustomError(_retval);
} else if (_error == RevertType.Panic) {
uint256 a = uint256(0) / uint256(0);
a;
}
emit Approved(owner, value, data);
return _retval;
}
}

View File

@@ -0,0 +1,10 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {ERC20} from "../../token/ERC20/ERC20.sol";
abstract contract ERC20ApprovalMock is ERC20 {
function _approve(address owner, address spender, uint256 amount, bool) internal virtual override {
super._approve(owner, spender, amount, true);
}
}

View File

@@ -0,0 +1,17 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {ERC20} from "../../token/ERC20/ERC20.sol";
abstract contract ERC20DecimalsMock is ERC20 {
uint8 private immutable _decimals;
constructor(uint8 decimals_) {
_decimals = decimals_;
}
function decimals() public view override returns (uint8) {
return _decimals;
}
}

View File

@@ -0,0 +1,9 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
contract ERC20ExcessDecimalsMock {
function decimals() public pure returns (uint256) {
return type(uint256).max;
}
}

View File

@@ -0,0 +1,26 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {ERC20FlashMint} from "../../token/ERC20/extensions/ERC20FlashMint.sol";
abstract contract ERC20FlashMintMock is ERC20FlashMint {
uint256 _flashFeeAmount;
address _flashFeeReceiverAddress;
function setFlashFee(uint256 amount) public {
_flashFeeAmount = amount;
}
function _flashFee(address, uint256) internal view override returns (uint256) {
return _flashFeeAmount;
}
function setFlashFeeReceiver(address receiver) public {
_flashFeeReceiverAddress = receiver;
}
function _flashFeeReceiver() internal view override returns (address) {
return _flashFeeReceiverAddress;
}
}

View File

@@ -0,0 +1,13 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {ERC20} from "../../token/ERC20/ERC20.sol";
// contract that replicate USDT (0xdac17f958d2ee523a2206206994597c13d831ec7) approval behavior
abstract contract ERC20ForceApproveMock is ERC20 {
function approve(address spender, uint256 amount) public virtual override returns (bool) {
require(amount == 0 || allowance(msg.sender, spender) == 0, "USDT approval failure");
return super.approve(spender, amount);
}
}

View File

@@ -0,0 +1,16 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {ERC20} from "../../token/ERC20/ERC20.sol";
contract ERC20Mock is ERC20 {
constructor() ERC20("ERC20Mock", "E20M") {}
function mint(address account, uint256 amount) external {
_mint(account, amount);
}
function burn(address account, uint256 amount) external {
_burn(account, amount);
}
}

View File

@@ -0,0 +1,8 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {ERC20} from "../../token/ERC20/ERC20.sol";
import {Multicall} from "../../utils/Multicall.sol";
abstract contract ERC20MulticallMock is ERC20, Multicall {}

View File

@@ -0,0 +1,28 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {ERC20} from "../../token/ERC20/ERC20.sol";
abstract contract ERC20NoReturnMock is ERC20 {
function transfer(address to, uint256 amount) public override returns (bool) {
super.transfer(to, amount);
assembly {
return(0, 0)
}
}
function transferFrom(address from, address to, uint256 amount) public override returns (bool) {
super.transferFrom(from, to, amount);
assembly {
return(0, 0)
}
}
function approve(address spender, uint256 amount) public override returns (bool) {
super.approve(spender, amount);
assembly {
return(0, 0)
}
}
}

View File

@@ -0,0 +1,39 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {ERC20} from "../../token/ERC20/ERC20.sol";
import {Address} from "../../utils/Address.sol";
contract ERC20Reentrant is ERC20("TEST", "TST") {
enum Type {
No,
Before,
After
}
Type private _reenterType;
address private _reenterTarget;
bytes private _reenterData;
function scheduleReenter(Type when, address target, bytes calldata data) external {
_reenterType = when;
_reenterTarget = target;
_reenterData = data;
}
function functionCall(address target, bytes memory data) public returns (bytes memory) {
return Address.functionCall(target, data);
}
function _update(address from, address to, uint256 amount) internal override {
if (_reenterType == Type.Before) {
_reenterType = Type.No;
functionCall(_reenterTarget, _reenterData);
}
super._update(from, to, amount);
if (_reenterType == Type.After) {
_reenterType = Type.No;
functionCall(_reenterTarget, _reenterData);
}
}
}

View File

@@ -0,0 +1,19 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {ERC20} from "../../token/ERC20/ERC20.sol";
abstract contract ERC20ReturnFalseMock is ERC20 {
function transfer(address, uint256) public pure override returns (bool) {
return false;
}
function transferFrom(address, address, uint256) public pure override returns (bool) {
return false;
}
function approve(address, uint256) public pure override returns (bool) {
return false;
}
}

View File

@@ -0,0 +1,253 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {ERC20Permit} from "../../token/ERC20/extensions/ERC20Permit.sol";
import {Math} from "../../utils/math/Math.sol";
import {IVotes} from "../../governance/utils/IVotes.sol";
import {SafeCast} from "../../utils/math/SafeCast.sol";
import {ECDSA} from "../../utils/cryptography/ECDSA.sol";
/**
* @dev Copied from the master branch at commit 86de1e8b6c3fa6b4efa4a5435869d2521be0f5f5
*/
abstract contract ERC20VotesLegacyMock is IVotes, ERC20Permit {
struct Checkpoint {
uint32 fromBlock;
uint224 votes;
}
bytes32 private constant _DELEGATION_TYPEHASH =
keccak256("Delegation(address delegatee,uint256 nonce,uint256 expiry)");
mapping(address account => address) private _delegatee;
mapping(address delegatee => Checkpoint[]) private _checkpoints;
Checkpoint[] private _totalSupplyCheckpoints;
/**
* @dev Get the `pos`-th checkpoint for `account`.
*/
function checkpoints(address account, uint32 pos) public view virtual returns (Checkpoint memory) {
return _checkpoints[account][pos];
}
/**
* @dev Get number of checkpoints for `account`.
*/
function numCheckpoints(address account) public view virtual returns (uint32) {
return SafeCast.toUint32(_checkpoints[account].length);
}
/**
* @dev Get the address `account` is currently delegating to.
*/
function delegates(address account) public view virtual returns (address) {
return _delegatee[account];
}
/**
* @dev Gets the current votes balance for `account`
*/
function getVotes(address account) public view virtual returns (uint256) {
uint256 pos = _checkpoints[account].length;
unchecked {
return pos == 0 ? 0 : _checkpoints[account][pos - 1].votes;
}
}
/**
* @dev Retrieve the number of votes for `account` at the end of `blockNumber`.
*
* Requirements:
*
* - `blockNumber` must have been already mined
*/
function getPastVotes(address account, uint256 blockNumber) public view virtual returns (uint256) {
require(blockNumber < block.number, "ERC20Votes: block not yet mined");
return _checkpointsLookup(_checkpoints[account], blockNumber);
}
/**
* @dev Retrieve the `totalSupply` at the end of `blockNumber`. Note, this value is the sum of all balances.
* It is NOT the sum of all the delegated votes!
*
* Requirements:
*
* - `blockNumber` must have been already mined
*/
function getPastTotalSupply(uint256 blockNumber) public view virtual returns (uint256) {
require(blockNumber < block.number, "ERC20Votes: block not yet mined");
return _checkpointsLookup(_totalSupplyCheckpoints, blockNumber);
}
/**
* @dev Lookup a value in a list of (sorted) checkpoints.
*/
function _checkpointsLookup(Checkpoint[] storage ckpts, uint256 blockNumber) private view returns (uint256) {
// We run a binary search to look for the earliest checkpoint taken after `blockNumber`.
//
// Initially we check if the block is recent to narrow the search range.
// During the loop, the index of the wanted checkpoint remains in the range [low-1, high).
// With each iteration, either `low` or `high` is moved towards the middle of the range to maintain the
// invariant.
// - If the middle checkpoint is after `blockNumber`, we look in [low, mid)
// - If the middle checkpoint is before or equal to `blockNumber`, we look in [mid+1, high)
// Once we reach a single value (when low == high), we've found the right checkpoint at the index high-1, if not
// out of bounds (in which case we're looking too far in the past and the result is 0).
// Note that if the latest checkpoint available is exactly for `blockNumber`, we end up with an index that is
// past the end of the array, so we technically don't find a checkpoint after `blockNumber`, but it works out
// the same.
uint256 length = ckpts.length;
uint256 low = 0;
uint256 high = length;
if (length > 5) {
uint256 mid = length - Math.sqrt(length);
if (_unsafeAccess(ckpts, mid).fromBlock > blockNumber) {
high = mid;
} else {
low = mid + 1;
}
}
while (low < high) {
uint256 mid = Math.average(low, high);
if (_unsafeAccess(ckpts, mid).fromBlock > blockNumber) {
high = mid;
} else {
low = mid + 1;
}
}
unchecked {
return high == 0 ? 0 : _unsafeAccess(ckpts, high - 1).votes;
}
}
/**
* @dev Delegate votes from the sender to `delegatee`.
*/
function delegate(address delegatee) public virtual {
_delegate(_msgSender(), delegatee);
}
/**
* @dev Delegates votes from signer to `delegatee`
*/
function delegateBySig(
address delegatee,
uint256 nonce,
uint256 expiry,
uint8 v,
bytes32 r,
bytes32 s
) public virtual {
require(block.timestamp <= expiry, "ERC20Votes: signature expired");
address signer = ECDSA.recover(
_hashTypedDataV4(keccak256(abi.encode(_DELEGATION_TYPEHASH, delegatee, nonce, expiry))),
v,
r,
s
);
require(nonce == _useNonce(signer), "ERC20Votes: invalid nonce");
_delegate(signer, delegatee);
}
/**
* @dev Maximum token supply. Defaults to `type(uint224).max` (2^224^ - 1).
*/
function _maxSupply() internal view virtual returns (uint224) {
return type(uint224).max;
}
/**
* @dev Move voting power when tokens are transferred.
*
* Emits a {IVotes-DelegateVotesChanged} event.
*/
function _update(address from, address to, uint256 amount) internal virtual override {
super._update(from, to, amount);
if (from == address(0)) {
require(totalSupply() <= _maxSupply(), "ERC20Votes: total supply risks overflowing votes");
_writeCheckpoint(_totalSupplyCheckpoints, _add, amount);
}
if (to == address(0)) {
_writeCheckpoint(_totalSupplyCheckpoints, _subtract, amount);
}
_moveVotingPower(delegates(from), delegates(to), amount);
}
/**
* @dev Change delegation for `delegator` to `delegatee`.
*
* Emits events {IVotes-DelegateChanged} and {IVotes-DelegateVotesChanged}.
*/
function _delegate(address delegator, address delegatee) internal virtual {
address currentDelegate = delegates(delegator);
uint256 delegatorBalance = balanceOf(delegator);
_delegatee[delegator] = delegatee;
emit DelegateChanged(delegator, currentDelegate, delegatee);
_moveVotingPower(currentDelegate, delegatee, delegatorBalance);
}
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);
emit DelegateVotesChanged(src, oldWeight, newWeight);
}
if (dst != address(0)) {
(uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[dst], _add, amount);
emit DelegateVotesChanged(dst, oldWeight, newWeight);
}
}
}
function _writeCheckpoint(
Checkpoint[] storage ckpts,
function(uint256, uint256) view returns (uint256) op,
uint256 delta
) private returns (uint256 oldWeight, uint256 newWeight) {
uint256 pos = ckpts.length;
unchecked {
Checkpoint memory oldCkpt = pos == 0 ? Checkpoint(0, 0) : _unsafeAccess(ckpts, pos - 1);
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)})
);
}
}
}
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 Access an element of the array without performing bounds check. The position is assumed to be within bounds.
*/
function _unsafeAccess(Checkpoint[] storage ckpts, uint256 pos) private pure returns (Checkpoint storage result) {
assembly {
mstore(0, ckpts.slot)
result.slot := add(keccak256(0, 0x20), pos)
}
}
}

View File

@@ -0,0 +1,29 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {ERC20Votes} from "../../token/ERC20/extensions/ERC20Votes.sol";
import {ERC721Votes} from "../../token/ERC721/extensions/ERC721Votes.sol";
import {SafeCast} from "../../utils/math/SafeCast.sol";
abstract contract ERC20VotesTimestampMock is ERC20Votes {
function clock() public view virtual override returns (uint48) {
return SafeCast.toUint48(block.timestamp);
}
// solhint-disable-next-line func-name-mixedcase
function CLOCK_MODE() public view virtual override returns (string memory) {
return "mode=timestamp";
}
}
abstract contract ERC721VotesTimestampMock is ERC721Votes {
function clock() public view virtual override returns (uint48) {
return SafeCast.toUint48(block.timestamp);
}
// solhint-disable-next-line func-name-mixedcase
function CLOCK_MODE() public view virtual override returns (string memory) {
return "mode=timestamp";
}
}

View File

@@ -0,0 +1,23 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {ERC4626} from "../../token/ERC20/extensions/ERC4626.sol";
abstract contract ERC4626LimitsMock is ERC4626 {
uint256 _maxDeposit;
uint256 _maxMint;
constructor() {
_maxDeposit = 100 ether;
_maxMint = 100 ether;
}
function maxDeposit(address) public view override returns (uint256) {
return _maxDeposit;
}
function maxMint(address) public view override returns (uint256) {
return _maxMint;
}
}

View File

@@ -0,0 +1,17 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {IERC20, ERC20} from "../../token/ERC20/ERC20.sol";
import {ERC4626} from "../../token/ERC20/extensions/ERC4626.sol";
contract ERC4626Mock is ERC4626 {
constructor(address underlying) ERC20("ERC4626Mock", "E4626M") ERC4626(IERC20(underlying)) {}
function mint(address account, uint256 amount) external {
_mint(account, amount);
}
function burn(address account, uint256 amount) external {
_burn(account, amount);
}
}

View File

@@ -0,0 +1,17 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {ERC4626} from "../../token/ERC20/extensions/ERC4626.sol";
abstract contract ERC4626OffsetMock is ERC4626 {
uint8 private immutable _offset;
constructor(uint8 offset_) {
_offset = offset_;
}
function _decimalsOffset() internal view virtual override returns (uint8) {
return _offset;
}
}

View File

@@ -0,0 +1,40 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {ERC4626Fees} from "../docs/ERC4626Fees.sol";
abstract contract ERC4626FeesMock is ERC4626Fees {
uint256 private immutable _entryFeeBasisPointValue;
address private immutable _entryFeeRecipientValue;
uint256 private immutable _exitFeeBasisPointValue;
address private immutable _exitFeeRecipientValue;
constructor(
uint256 entryFeeBasisPoints,
address entryFeeRecipient,
uint256 exitFeeBasisPoints,
address exitFeeRecipient
) {
_entryFeeBasisPointValue = entryFeeBasisPoints;
_entryFeeRecipientValue = entryFeeRecipient;
_exitFeeBasisPointValue = exitFeeBasisPoints;
_exitFeeRecipientValue = exitFeeRecipient;
}
function _entryFeeBasisPoints() internal view virtual override returns (uint256) {
return _entryFeeBasisPointValue;
}
function _entryFeeRecipient() internal view virtual override returns (address) {
return _entryFeeRecipientValue;
}
function _exitFeeBasisPoints() internal view virtual override returns (uint256) {
return _exitFeeBasisPointValue;
}
function _exitFeeRecipient() internal view virtual override returns (address) {
return _exitFeeRecipientValue;
}
}

View File

@@ -0,0 +1,42 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {ERC721} from "../../token/ERC721/ERC721.sol";
import {ERC721Consecutive} from "../../token/ERC721/extensions/ERC721Consecutive.sol";
import {ERC721Enumerable} from "../../token/ERC721/extensions/ERC721Enumerable.sol";
contract ERC721ConsecutiveEnumerableMock is ERC721Consecutive, ERC721Enumerable {
constructor(
string memory name,
string memory symbol,
address[] memory receivers,
uint96[] memory amounts
) ERC721(name, symbol) {
for (uint256 i = 0; i < receivers.length; ++i) {
_mintConsecutive(receivers[i], amounts[i]);
}
}
function supportsInterface(
bytes4 interfaceId
) public view virtual override(ERC721, ERC721Enumerable) returns (bool) {
return super.supportsInterface(interfaceId);
}
function _ownerOf(uint256 tokenId) internal view virtual override(ERC721, ERC721Consecutive) returns (address) {
return super._ownerOf(tokenId);
}
function _update(
address to,
uint256 tokenId,
address auth
) internal virtual override(ERC721Consecutive, ERC721Enumerable) returns (address) {
return super._update(to, tokenId, auth);
}
function _increaseBalance(address account, uint128 amount) internal virtual override(ERC721, ERC721Enumerable) {
super._increaseBalance(account, amount);
}
}

View File

@@ -0,0 +1,61 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {ERC721} from "../../token/ERC721/ERC721.sol";
import {ERC721Consecutive} from "../../token/ERC721/extensions/ERC721Consecutive.sol";
import {ERC721Pausable} from "../../token/ERC721/extensions/ERC721Pausable.sol";
import {ERC721Votes} from "../../token/ERC721/extensions/ERC721Votes.sol";
import {EIP712} from "../../utils/cryptography/EIP712.sol";
/**
* @title ERC721ConsecutiveMock
*/
contract ERC721ConsecutiveMock is ERC721Consecutive, ERC721Pausable, ERC721Votes {
uint96 private immutable _offset;
constructor(
string memory name,
string memory symbol,
uint96 offset,
address[] memory delegates,
address[] memory receivers,
uint96[] memory amounts
) ERC721(name, symbol) EIP712(name, "1") {
_offset = offset;
for (uint256 i = 0; i < delegates.length; ++i) {
_delegate(delegates[i], delegates[i]);
}
for (uint256 i = 0; i < receivers.length; ++i) {
_mintConsecutive(receivers[i], amounts[i]);
}
}
function _firstConsecutiveId() internal view virtual override returns (uint96) {
return _offset;
}
function _ownerOf(uint256 tokenId) internal view virtual override(ERC721, ERC721Consecutive) returns (address) {
return super._ownerOf(tokenId);
}
function _update(
address to,
uint256 tokenId,
address auth
) internal virtual override(ERC721Consecutive, ERC721Pausable, ERC721Votes) returns (address) {
return super._update(to, tokenId, auth);
}
function _increaseBalance(address account, uint128 amount) internal virtual override(ERC721, ERC721Votes) {
super._increaseBalance(account, amount);
}
}
contract ERC721ConsecutiveNoConstructorMintMock is ERC721Consecutive {
constructor(string memory name, string memory symbol) ERC721(name, symbol) {
_mint(msg.sender, 0);
}
}

View File

@@ -0,0 +1,47 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {IERC721Receiver} from "../../token/ERC721/IERC721Receiver.sol";
contract ERC721ReceiverMock is IERC721Receiver {
enum RevertType {
None,
RevertWithoutMessage,
RevertWithMessage,
RevertWithCustomError,
Panic
}
bytes4 private immutable _retval;
RevertType private immutable _error;
event Received(address operator, address from, uint256 tokenId, bytes data, uint256 gas);
error CustomError(bytes4);
constructor(bytes4 retval, RevertType error) {
_retval = retval;
_error = error;
}
function onERC721Received(
address operator,
address from,
uint256 tokenId,
bytes memory data
) public returns (bytes4) {
if (_error == RevertType.RevertWithoutMessage) {
revert();
} else if (_error == RevertType.RevertWithMessage) {
revert("ERC721ReceiverMock: reverting");
} else if (_error == RevertType.RevertWithCustomError) {
revert CustomError(_retval);
} else if (_error == RevertType.Panic) {
uint256 a = uint256(0) / uint256(0);
a;
}
emit Received(operator, from, tokenId, data, gasleft());
return _retval;
}
}

View File

@@ -0,0 +1,17 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {ERC721URIStorage} from "../../token/ERC721/extensions/ERC721URIStorage.sol";
abstract contract ERC721URIStorageMock is ERC721URIStorage {
string private _baseTokenURI;
function _baseURI() internal view virtual override returns (string memory) {
return _baseTokenURI;
}
function setBaseURI(string calldata newBaseTokenURI) public {
_baseTokenURI = newBaseTokenURI;
}
}