mirror of
https://github.com/vacp2p/minime.git
synced 2026-01-08 22:57:57 -05:00
committed by
r4bbit
parent
38d62c5517
commit
a522ebb09d
21
.gas-report
21
.gas-report
@@ -1,30 +1,29 @@
|
||||
| contracts/MiniMeToken.sol:MiniMeToken contract | | | | | |
|
||||
|------------------------------------------------|-----------------|-------|--------|-------|---------|
|
||||
| Deployment Cost | Deployment Size | | | | |
|
||||
| 1651926 | 9241 | | | | |
|
||||
| 2149485 | 12251 | | | | |
|
||||
| Function Name | min | avg | median | max | # calls |
|
||||
| allowance | 0 | 60 | 0 | 786 | 13 |
|
||||
| approve | 0 | 15018 | 14715 | 31708 | 10 |
|
||||
| approveAndCall | 0 | 31204 | 0 | 93613 | 3 |
|
||||
| allowance | 0 | 62 | 0 | 808 | 13 |
|
||||
| approve | 0 | 15064 | 14767 | 31771 | 10 |
|
||||
| approveAndCall | 0 | 31232 | 0 | 93698 | 3 |
|
||||
| balanceOf | 0 | 550 | 0 | 2731 | 63 |
|
||||
| balanceOfAt | 0 | 905 | 0 | 4027 | 78 |
|
||||
| changeController | 0 | 593 | 0 | 3558 | 6 |
|
||||
| claimTokens | 9582 | 41342 | 57222 | 57222 | 3 |
|
||||
| claimTokens | 9537 | 41267 | 57132 | 57132 | 3 |
|
||||
| controller | 0 | 0 | 0 | 0 | 9 |
|
||||
| decimals | 0 | 0 | 0 | 0 | 9 |
|
||||
| destroyTokens | 2286 | 5184 | 4288 | 8979 | 3 |
|
||||
| destroyTokens | 2286 | 5185 | 4288 | 8983 | 3 |
|
||||
| enableTransfers | 0 | 0 | 0 | 0 | 3 |
|
||||
| generateTokens | 0 | 14007 | 0 | 95829 | 62 |
|
||||
| generateTokens | 0 | 14015 | 0 | 95885 | 62 |
|
||||
| name | 0 | 0 | 0 | 0 | 9 |
|
||||
| parentSnapShotBlock | 0 | 0 | 0 | 0 | 10 |
|
||||
| parentToken | 0 | 0 | 0 | 0 | 10 |
|
||||
| receive | 7960 | 7979 | 7979 | 7998 | 2 |
|
||||
| symbol | 0 | 0 | 0 | 0 | 9 |
|
||||
| totalSupply | 0 | 286 | 0 | 2480 | 22 |
|
||||
| totalSupplyAt | 0 | 866 | 0 | 3637 | 17 |
|
||||
| transfer | 571 | 39327 | 50440 | 93129 | 20 |
|
||||
| transferFrom | 0 | 16831 | 3495 | 66552 | 7 |
|
||||
| totalSupplyAt | 0 | 873 | 0 | 3659 | 17 |
|
||||
| transfer | 526 | 39283 | 50395 | 93092 | 20 |
|
||||
| transferFrom | 0 | 16834 | 3495 | 66574 | 7 |
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
124
.gas-snapshot
124
.gas-snapshot
@@ -1,45 +1,123 @@
|
||||
<<<<<<< HEAD
|
||||
<<<<<<< HEAD
|
||||
AllowanceTest:testAllowance() (gas: 42712)
|
||||
AllowanceTest:testAllowanceAlreadySet() (gas: 36809)
|
||||
AllowanceTest:testAllowanceReset() (gas: 45925)
|
||||
AllowanceTest:testApproveAndCall() (gas: 98532)
|
||||
AllowanceTest:testApproveTransferDisabled() (gas: 7968)
|
||||
||||||| parent of fd986cf (add missing return on approve)
|
||||
AllowanceTest:testAllowance() (gas: 42712)
|
||||
AllowanceTest:testAllowanceAlreadySet() (gas: 36809)
|
||||
AllowanceTest:testAllowanceReset() (gas: 45925)
|
||||
AllowanceTest:testApproveAndCall() (gas: 98532)
|
||||
AllowanceTest:testApproveTransferDisabled() (gas: 7968)
|
||||
=======
|
||||
AllowanceTest:testAllowance() (gas: 42775)
|
||||
AllowanceTest:testAllowanceAlreadySet() (gas: 36905)
|
||||
AllowanceTest:testAllowanceReset() (gas: 46071)
|
||||
AllowanceTest:testApproveAndCall() (gas: 98617)
|
||||
AllowanceTest:testApproveTransferDisabled() (gas: 7994)
|
||||
>>>>>>> fd986cf (add missing return on approve)
|
||||
AllowanceTest:testDeployment() (gas: 26711)
|
||||
AllowanceTest:testNoAllowance() (gas: 9462)
|
||||
AllowanceTest:testRejectedApproval() (gas: 13643)
|
||||
ClaimTokensTest:testClaimERC20() (gas: 63808)
|
||||
ClaimTokensTest:testClaimETH() (gas: 13682)
|
||||
ClaimTokensTest:testClaimSelf() (gas: 61290)
|
||||
AllowanceTest:testRejectedApproval() (gas: 13683)
|
||||
ClaimTokensTest:testClaimERC20() (gas: 63718)
|
||||
ClaimTokensTest:testClaimETH() (gas: 13637)
|
||||
ClaimTokensTest:testClaimSelf() (gas: 61200)
|
||||
ClaimTokensTest:testDeployment() (gas: 26595)
|
||||
CreateCloneTokenTest:testCloneFutureSnapshot() (gas: 101370)
|
||||
CreateCloneTokenTest:testCreateCloneToken() (gas: 1692517)
|
||||
CreateCloneTokenTest:testCloneFutureSnapshot() (gas: 101288)
|
||||
CreateCloneTokenTest:testCreateCloneToken() (gas: 2190766)
|
||||
CreateCloneTokenTest:testDeployment() (gas: 26550)
|
||||
CreateCloneTokenTest:testGenerateTokens() (gas: 102115)
|
||||
CreateCloneTokenTest:testGenerateTokens() (gas: 102171)
|
||||
DestroyTokensTest:testDeployment() (gas: 26595)
|
||||
DestroyTokensTest:testDestroyTokens() (gas: 13479)
|
||||
DestroyTokensTest:testDestroyTokens() (gas: 13483)
|
||||
DestroyTokensTest:testDestroyTokensNotEnoughBalance() (gas: 9644)
|
||||
DestroyTokensTest:testDestroyTokensNotEnoughSupply() (gas: 7975)
|
||||
GenerateTokensTest:testDeployment() (gas: 26550)
|
||||
GenerateTokensTest:testGenerateTokens() (gas: 109561)
|
||||
GenerateTokensTest:testGenerateTokens() (gas: 109587)
|
||||
GenerateTokensTest:testGenerateTokensSupplyOverflow() (gas: 3126)
|
||||
GenerateTokensTest:test_RevertWhen_SenderIsNotController() (gas: 14994)
|
||||
GenerateTokensTest:test_RevertWhen_SenderIsNotController() (gas: 15016)
|
||||
MiniMeTokenTest:testDeployment() (gas: 26535)
|
||||
ReceiveTest:testAcceptingEther() (gas: 18628)
|
||||
ReceiveTest:testDeployment() (gas: 26595)
|
||||
ReceiveTest:testRejectingEther() (gas: 18691)
|
||||
ReentrancyTest:testAttack() (gas: 229327)
|
||||
ReentrancyTest:testAttack() (gas: 229445)
|
||||
TestPermit:testDeployment() (gas: 26573)
|
||||
TestPermit:testInvalidAllowance() (gas: 84344)
|
||||
TestPermit:testInvalidBalance() (gas: 67425)
|
||||
TestPermit:testPermit() (gas: 84547)
|
||||
TestPermit:testRevertExpiredPermit() (gas: 27878)
|
||||
TestPermit:testRevertInvalidNonce() (gas: 57309)
|
||||
TestPermit:testRevertInvalidSigner() (gas: 56070)
|
||||
TestPermit:testRevertSignatureReplay() (gas: 96596)
|
||||
TestPermit:testTransferFromLimitedPermit() (gas: 216258)
|
||||
TestPermit:testTransferFromMaxPermit() (gas: 236197)
|
||||
TestSnapshotReads:testDeployment() (gas: 26550)
|
||||
<<<<<<< HEAD
|
||||
TestSnapshotReads:testSnapshotReads() (gas: 755896)
|
||||
||||||| parent of fd986cf (add missing return on approve)
|
||||
TestSnapshotReads:testSnapshotReads() (gas: 755896)
|
||||
TestPermit:testDeployment() (gas: 45858)
|
||||
TestPermit:testInvalidAllowance() (gas: 84397)
|
||||
TestPermit:testInvalidBalance() (gas: 67478)
|
||||
TestPermit:testPermit() (gas: 84644)
|
||||
TestPermit:testRevertExpiredPermit() (gas: 27953)
|
||||
TestPermit:testRevertInvalidNonce() (gas: 57362)
|
||||
TestPermit:testRevertInvalidSigner() (gas: 56145)
|
||||
TestPermit:testRevertSignatureReplay() (gas: 96746)
|
||||
TestPermit:testTransferFromLimitedPermit() (gas: 216308)
|
||||
TestPermit:testTransferFromMaxPermit() (gas: 236247)
|
||||
=======
|
||||
TestSnapshotReads:testSnapshotReads() (gas: 756322)
|
||||
>>>>>>> fd986cf (add missing return on approve)
|
||||
TransferTest:testDeployment() (gas: 26617)
|
||||
TransferTest:testDoubleTransfer() (gas: 92515)
|
||||
TransferTest:testDoubleTransfer2() (gas: 70668)
|
||||
TransferTest:testInvalidDestinationTransfer() (gas: 6447)
|
||||
TransferTest:testInvalidDestinationTransfer2() (gas: 6444)
|
||||
TransferTest:testMultipleTransferToSame() (gas: 114745)
|
||||
TransferTest:testMultipleTransferToSame2() (gas: 92942)
|
||||
TransferTest:testRejectedTransfer() (gas: 59966)
|
||||
TransferTest:testTransfer() (gas: 81763)
|
||||
TransferTest:testTransfer2() (gas: 59939)
|
||||
TransferTest:testTransferControllerZero() (gas: 59886)
|
||||
TransferTest:testTransferDisabled() (gas: 8013)
|
||||
TransferTest:testDoubleTransfer() (gas: 92425)
|
||||
TransferTest:testDoubleTransfer2() (gas: 70578)
|
||||
TransferTest:testInvalidDestinationTransfer() (gas: 6402)
|
||||
TransferTest:testInvalidDestinationTransfer2() (gas: 6399)
|
||||
TransferTest:testMultipleTransferToSame() (gas: 114655)
|
||||
TransferTest:testMultipleTransferToSame2() (gas: 92852)
|
||||
TransferTest:testRejectedTransfer() (gas: 59921)
|
||||
TransferTest:testTransfer() (gas: 81718)
|
||||
TransferTest:testTransfer2() (gas: 59894)
|
||||
TransferTest:testTransferControllerZero() (gas: 59841)
|
||||
TransferTest:testTransferDisabled() (gas: 7968)
|
||||
TransferTest:testTransferFromDisabled() (gas: 6526)
|
||||
TransferTest:testTransferNoBalance() (gas: 16972)
|
||||
<<<<<<< HEAD
|
||||
TransferTest:testTransferNoBalance() (gas: 16972)
|
||||
||||||| parent of d658aa3 (Make MiniMe implement ERC2612)
|
||||
AllowanceTest:testAllowance() (gas: 244303)
|
||||
AllowanceTest:testDeployment() (gas: 45814)
|
||||
CreateCloneTokenTest:testCreateCloneToken() (gas: 2182389)
|
||||
CreateCloneTokenTest:testDeployment() (gas: 45769)
|
||||
CreateCloneTokenTest:testGenerateTokens() (gas: 2061699)
|
||||
DestroyTokensTest:testDeployment() (gas: 45598)
|
||||
DestroyTokensTest:testDestroyTokens() (gas: 124942)
|
||||
GenerateTokensTest:testDeployment() (gas: 45553)
|
||||
GenerateTokensTest:testGenerateTokens() (gas: 114621)
|
||||
GenerateTokensTest:test_RevertWhen_SenderIsNotController() (gas: 14930)
|
||||
MiniMeTokenTest:testDeployment() (gas: 45598)
|
||||
ReentrancyTest:testAttack() (gas: 229394)
|
||||
TransferTest:testDeployment() (gas: 45814)
|
||||
TransferTest:testTransfer() (gas: 201281)
|
||||
=======
|
||||
AllowanceTest:testAllowance() (gas: 244406)
|
||||
AllowanceTest:testDeployment() (gas: 45880)
|
||||
CreateCloneTokenTest:testCreateCloneToken() (gas: 2681910)
|
||||
CreateCloneTokenTest:testDeployment() (gas: 45835)
|
||||
CreateCloneTokenTest:testGenerateTokens() (gas: 2561311)
|
||||
DestroyTokensTest:testDeployment() (gas: 45664)
|
||||
DestroyTokensTest:testDestroyTokens() (gas: 124942)
|
||||
GenerateTokensTest:testDeployment() (gas: 45619)
|
||||
GenerateTokensTest:testGenerateTokens() (gas: 114621)
|
||||
GenerateTokensTest:test_RevertWhen_SenderIsNotController() (gas: 14930)
|
||||
MiniMeTokenTest:testDeployment() (gas: 45664)
|
||||
ReentrancyTest:testAttack() (gas: 229482)
|
||||
TransferTest:testDeployment() (gas: 45880)
|
||||
TransferTest:testTransfer() (gas: 201303)
|
||||
>>>>>>> d658aa3 (Make MiniMe implement ERC2612)
|
||||
||||||| parent of fd986cf (add missing return on approve)
|
||||
TransferTest:testTransferNoBalance() (gas: 16972)
|
||||
=======
|
||||
TransferTest:testTransferNoBalance() (gas: 16927)
|
||||
>>>>>>> fd986cf (add missing return on approve)
|
||||
|
||||
@@ -12,6 +12,8 @@ error Overflow();
|
||||
error AllowanceAlreadySet();
|
||||
error OperationFailed();
|
||||
error ControllerNotSet();
|
||||
error ERC2612ExpiredSignature(uint256 deadline);
|
||||
error ERC2612InvalidSigner(address signer, address owner);
|
||||
/*
|
||||
Copyright 2016, Jordi Baylina
|
||||
|
||||
@@ -33,6 +35,10 @@ import { Controlled } from "./Controlled.sol";
|
||||
import { TokenController } from "./TokenController.sol";
|
||||
import { ApproveAndCallFallBack } from "./ApproveAndCallFallBack.sol";
|
||||
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
|
||||
import { IERC20Permit } from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol";
|
||||
import { EIP712 } from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";
|
||||
import { ECDSA } from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
|
||||
import { Nonces } from "./Nonces.sol";
|
||||
|
||||
/// @title MiniMeBase Contract
|
||||
/// @author Jordi Baylina
|
||||
@@ -40,11 +46,13 @@ import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
|
||||
/// token using the token distribution at a given block, this will allow DAO's
|
||||
/// and DApps to upgrade their features in a decentralized manner without
|
||||
/// affecting the original token
|
||||
abstract contract MiniMeBase is Controlled, IERC20 {
|
||||
abstract contract MiniMeBase is Controlled, IERC20, IERC20Permit, EIP712, Nonces {
|
||||
string public name; //The Token's name: e.g. DigixDAO Tokens
|
||||
uint8 public immutable decimals; //Number of decimals of the smallest unit
|
||||
string public symbol; //An identifier: e.g. REP
|
||||
string public constant TOKEN_VERSION = "MMT_0.2"; //An arbitrary versioning scheme
|
||||
bytes32 private constant PERMIT_TYPEHASH =
|
||||
keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)");
|
||||
|
||||
/// @dev `Checkpoint` is the structure that attaches a block number to a
|
||||
/// given value, the block number attached is the one that last changed the
|
||||
@@ -98,7 +106,9 @@ abstract contract MiniMeBase is Controlled, IERC20 {
|
||||
uint8 _decimalUnits,
|
||||
string memory _tokenSymbol,
|
||||
bool _transfersEnabled
|
||||
) {
|
||||
)
|
||||
EIP712(_tokenName, TOKEN_VERSION)
|
||||
{
|
||||
name = _tokenName; // Set the name
|
||||
decimals = _decimalUnits; // Set the decimals
|
||||
symbol = _tokenSymbol; // Set the symbol
|
||||
@@ -200,23 +210,58 @@ abstract contract MiniMeBase is Controlled, IERC20 {
|
||||
/// @param _amount The amount of tokens to be approved for transfer
|
||||
/// @return success True if the approval was successful
|
||||
function approve(address _spender, uint256 _amount) public returns (bool success) {
|
||||
return doApprove(msg.sender, _spender, _amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc IERC20Permit
|
||||
*/
|
||||
function permit(
|
||||
address owner,
|
||||
address spender,
|
||||
uint256 value,
|
||||
uint256 deadline,
|
||||
uint8 v,
|
||||
bytes32 r,
|
||||
bytes32 s
|
||||
)
|
||||
public
|
||||
virtual
|
||||
{
|
||||
if (block.timestamp > deadline) {
|
||||
revert ERC2612ExpiredSignature(deadline);
|
||||
}
|
||||
|
||||
bytes32 structHash = keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));
|
||||
|
||||
bytes32 hash = _hashTypedDataV4(structHash);
|
||||
|
||||
address signer = ECDSA.recover(hash, v, r, s);
|
||||
if (signer != owner) {
|
||||
revert ERC2612InvalidSigner(signer, owner);
|
||||
}
|
||||
|
||||
doApprove(owner, spender, value);
|
||||
}
|
||||
|
||||
function doApprove(address _owner, address _spender, uint256 _amount) internal returns (bool) {
|
||||
if (!transfersEnabled) revert TransfersDisabled();
|
||||
|
||||
// To change the approve amount you first have to reduce the addresses`
|
||||
// allowance to zero by calling `approve(_spender,0)` if it is not
|
||||
// already 0 to mitigate the race condition described here:
|
||||
// https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
|
||||
if ((_amount != 0) && (allowed[msg.sender][_spender] != 0)) revert AllowanceAlreadySet();
|
||||
if ((_amount != 0) && (allowed[_owner][_spender] != 0)) revert AllowanceAlreadySet();
|
||||
|
||||
// Alerts the token controller of the approve function call
|
||||
if (isContract(controller)) {
|
||||
if (!TokenController(controller).onApprove(msg.sender, _spender, _amount)) {
|
||||
if (!TokenController(controller).onApprove(_owner, _spender, _amount)) {
|
||||
revert ControllerRejected();
|
||||
}
|
||||
}
|
||||
|
||||
allowed[msg.sender][_spender] = _amount;
|
||||
emit Approval(msg.sender, _spender, _amount);
|
||||
allowed[_owner][_spender] = _amount;
|
||||
emit Approval(_owner, _spender, _amount);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -300,6 +345,21 @@ abstract contract MiniMeBase is Controlled, IERC20 {
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// @inheritdoc IERC20Permit
|
||||
///
|
||||
function nonces(address owner) public view virtual override(IERC20Permit, Nonces) returns (uint256) {
|
||||
return super.nonces(owner);
|
||||
}
|
||||
|
||||
///
|
||||
/// @inheritdoc IERC20Permit
|
||||
///
|
||||
// solhint-disable-next-line func-name-mixedcase
|
||||
function DOMAIN_SEPARATOR() external view virtual returns (bytes32) {
|
||||
return _domainSeparatorV4();
|
||||
}
|
||||
|
||||
////////////////
|
||||
// Generate and destroy tokens
|
||||
////////////////
|
||||
|
||||
45
contracts/Nonces.sol
Normal file
45
contracts/Nonces.sol
Normal file
@@ -0,0 +1,45 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
/**
|
||||
* @dev Provides tracking nonces for addresses. Nonces will only increment.
|
||||
*/
|
||||
abstract contract Nonces {
|
||||
/**
|
||||
* @dev The nonce used for an `account` is not the expected current nonce.
|
||||
*/
|
||||
error InvalidAccountNonce(address account, uint256 currentNonce);
|
||||
|
||||
mapping(address account => uint256) private _nonces;
|
||||
|
||||
/**
|
||||
* @dev Returns the next unused nonce for an address.
|
||||
*/
|
||||
function nonces(address owner) public view virtual returns (uint256) {
|
||||
return _nonces[owner];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Consumes a nonce.
|
||||
*
|
||||
* Returns the current value and increments nonce.
|
||||
*/
|
||||
function _useNonce(address owner) internal virtual returns (uint256) {
|
||||
// For each account, the nonce has an initial value of 0, can only be incremented by one, and cannot be
|
||||
// decremented or reset. This guarantees that the nonce never overflows.
|
||||
unchecked {
|
||||
// It is important to do x++ and not ++x here.
|
||||
return _nonces[owner]++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Same as {_useNonce} but checking that `nonce` is the next valid for `owner`.
|
||||
*/
|
||||
function _useCheckedNonce(address owner, uint256 nonce) internal virtual {
|
||||
uint256 current = _useNonce(owner);
|
||||
if (nonce != current) {
|
||||
revert InvalidAccountNonce(owner, current);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user