dexorder
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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 {}
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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";
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user