Merge branch 'master' into next-v5.0

This commit is contained in:
Francisco Giordano
2023-05-16 00:07:07 -03:00
308 changed files with 21085 additions and 11515 deletions

View File

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

View File

@ -0,0 +1,13 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../../token/ERC20/ERC20.sol";
// contract that replicate USDT (0xdac17f958d2ee523a2206206994597c13d831ec7) approval beavior
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.0;
import "../../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

@ -2,20 +2,27 @@
pragma solidity ^0.8.0;
contract ERC20NoReturnMock {
mapping(address => uint256) private _allowances;
import "../../token/ERC20/ERC20.sol";
function transfer(address, uint256) public {}
function transferFrom(address, address, uint256) public {}
function approve(address, uint256) public {}
function setAllowance(address account, uint256 allowance_) public {
_allowances[account] = allowance_;
abstract contract ERC20NoReturnMock is ERC20 {
function transfer(address to, uint256 amount) public override returns (bool) {
super.transfer(to, amount);
assembly {
return(0, 0)
}
}
function allowance(address owner, address) public view returns (uint256) {
return _allowances[owner];
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

@ -5,9 +5,7 @@ pragma solidity ^0.8.0;
import "../../token/ERC20/ERC20.sol";
import "../../token/ERC20/extensions/draft-ERC20Permit.sol";
contract ERC20PermitNoRevertMock is ERC20, ERC20Permit {
constructor() ERC20("ERC20PermitNoRevertMock", "ERC20PermitNoRevertMock") ERC20Permit("ERC20PermitNoRevertMock") {}
abstract contract ERC20PermitNoRevertMock is ERC20Permit {
function permitThatMayRevert(
address owner,
address spender,

View File

@ -0,0 +1,39 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../../token/ERC20/ERC20.sol";
import "../../token/ERC20/extensions/ERC4626.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

@ -2,26 +2,18 @@
pragma solidity ^0.8.0;
contract ERC20ReturnFalseMock {
mapping(address => uint256) private _allowances;
import "../../token/ERC20/ERC20.sol";
function transfer(address, uint256) public pure returns (bool) {
abstract contract ERC20ReturnFalseMock is ERC20 {
function transfer(address, uint256) public pure override returns (bool) {
return false;
}
function transferFrom(address, address, uint256) public pure returns (bool) {
function transferFrom(address, address, uint256) public pure override returns (bool) {
return false;
}
function approve(address, uint256) public pure returns (bool) {
function approve(address, uint256) public pure override returns (bool) {
return false;
}
function setAllowance(address account, uint256 allowance_) public {
_allowances[account] = allowance_;
}
function allowance(address owner, address) public view returns (uint256) {
return _allowances[owner];
}
}

View File

@ -1,27 +0,0 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract ERC20ReturnTrueMock {
mapping(address => uint256) private _allowances;
function transfer(address, uint256) public pure returns (bool) {
return true;
}
function transferFrom(address, address, uint256) public pure returns (bool) {
return true;
}
function approve(address, uint256) public pure returns (bool) {
return true;
}
function setAllowance(address account, uint256 allowance_) public {
_allowances[account] = allowance_;
}
function allowance(address owner, address) public view returns (uint256) {
return _allowances[owner];
}
}

View File

@ -0,0 +1,252 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../../token/ERC20/extensions/ERC20Permit.sol";
import "../../utils/math/Math.sol";
import "../../governance/utils/IVotes.sol";
import "../../utils/math/SafeCast.sol";
import "../../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 => address) private _delegates;
mapping(address => 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 override returns (address) {
return _delegates[account];
}
/**
* @dev Gets the current votes balance for `account`
*/
function getVotes(address account) public view virtual override 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 override 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 override 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 override {
_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 override {
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);
_delegates[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

@ -1,33 +0,0 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../../token/ERC20/extensions/ERC4626.sol";
abstract contract ERC4626DecimalsMock is ERC4626 {
using Math for uint256;
uint8 private immutable _decimals;
constructor(uint8 decimals_) {
_decimals = decimals_;
}
function decimals() public view virtual override returns (uint8) {
return _decimals;
}
function _initialConvertToShares(
uint256 assets,
Math.Rounding rounding
) internal view virtual override returns (uint256 shares) {
return assets.mulDiv(10 ** decimals(), 10 ** super.decimals(), rounding);
}
function _initialConvertToAssets(
uint256 shares,
Math.Rounding rounding
) internal view virtual override returns (uint256 assets) {
return shares.mulDiv(10 ** super.decimals(), 10 ** decimals(), rounding);
}
}

View File

@ -0,0 +1,16 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../../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.0;
import "../../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.0;
import "../docs/ERC4626Fees.sol";
abstract contract ERC4626FeesMock is ERC4626Fees {
uint256 private immutable _entryFeeBasePointValue;
address private immutable _entryFeeRecipientValue;
uint256 private immutable _exitFeeBasePointValue;
address private immutable _exitFeeRecipientValue;
constructor(
uint256 entryFeeBasePoint,
address entryFeeRecipient,
uint256 exitFeeBasePoint,
address exitFeeRecipient
) {
_entryFeeBasePointValue = entryFeeBasePoint;
_entryFeeRecipientValue = entryFeeRecipient;
_exitFeeBasePointValue = exitFeeBasePoint;
_exitFeeRecipientValue = exitFeeRecipient;
}
function _entryFeeBasePoint() internal view virtual override returns (uint256) {
return _entryFeeBasePointValue;
}
function _entryFeeRecipient() internal view virtual override returns (address) {
return _entryFeeRecipientValue;
}
function _exitFeeBasePoint() internal view virtual override returns (uint256) {
return _exitFeeBasePointValue;
}
function _exitFeeRecipient() internal view virtual override returns (address) {
return _exitFeeRecipientValue;
}
}

View File

@ -0,0 +1,40 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../../token/ERC20/extensions/ERC20Votes.sol";
import "../../token/ERC20/extensions/ERC20VotesComp.sol";
import "../../token/ERC721/extensions/ERC721Votes.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 ERC20VotesCompTimestampMock is ERC20VotesComp {
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";
}
}