make abstract and concrete versions

add gas reports

move event from abstract to concrete

lint
This commit is contained in:
Ricardo Guilherme Schmidt 2023-09-22 16:08:59 -03:00
parent 461d865527
commit 3f95a3bcf9
5 changed files with 126 additions and 82 deletions

View File

@ -1,7 +1,7 @@
| contracts/MiniMeToken.sol:MiniMeToken contract | | | | | |
|------------------------------------------------|-----------------|---------|---------|---------|---------|
| Deployment Cost | Deployment Size | | | | |
| 1788057 | 9919 | | | | |
| 1793495 | 9955 | | | | |
| Function Name | min | avg | median | max | # calls |
| allowance | 808 | 808 | 808 | 808 | 3 |
| approve | 30781 | 31244 | 31244 | 31708 | 2 |
@ -9,16 +9,16 @@
| balanceOfAt | 1142 | 2585 | 2363 | 3603 | 26 |
| changeController | 758 | 1318 | 758 | 3558 | 5 |
| controller | 2447 | 2447 | 2447 | 2447 | 6 |
| createCloneToken | 1832796 | 1832796 | 1832796 | 1832796 | 2 |
| createCloneToken | 1838245 | 1838245 | 1838245 | 1838245 | 2 |
| decimals | 294 | 294 | 294 | 294 | 6 |
| destroyTokens | 8956 | 8956 | 8956 | 8956 | 1 |
| generateTokens | 2541 | 82036 | 94453 | 95751 | 11 |
| destroyTokens | 9001 | 9001 | 9001 | 9001 | 1 |
| generateTokens | 2541 | 82077 | 94498 | 95796 | 11 |
| name | 3253 | 3253 | 3253 | 3253 | 6 |
| parentSnapShotBlock | 284 | 284 | 284 | 284 | 7 |
| parentToken | 305 | 305 | 305 | 305 | 7 |
| symbol | 3274 | 3274 | 3274 | 3274 | 6 |
| totalSupply | 1911 | 2917 | 1911 | 4930 | 6 |
| totalSupplyAt | 1995 | 3029 | 3003 | 4606 | 7 |
| totalSupplyAt | 1995 | 3028 | 3003 | 4603 | 7 |
| transfer | 75187 | 75187 | 75187 | 75187 | 1 |
| transferFrom | 3495 | 48093 | 66590 | 74194 | 3 |
@ -26,9 +26,9 @@
| contracts/MiniMeTokenFactory.sol:MiniMeTokenFactory contract | | | | | |
|--------------------------------------------------------------|-----------------|---------|---------|---------|---------|
| Deployment Cost | Deployment Size | | | | |
| 2111243 | 10577 | | | | |
| 2118450 | 10613 | | | | |
| Function Name | min | avg | median | max | # calls |
| createCloneToken | 1825218 | 1825218 | 1825218 | 1825218 | 2 |
| createCloneToken | 1830667 | 1830667 | 1830667 | 1830667 | 2 |

View File

@ -1,14 +1,14 @@
AllowanceTest:testAllowance() (gas: 244240)
AllowanceTest:testAllowance() (gas: 244285)
AllowanceTest:testDeployment() (gas: 45814)
CreateCloneTokenTest:testCreateCloneToken() (gas: 2165972)
CreateCloneTokenTest:testCreateCloneToken() (gas: 2171532)
CreateCloneTokenTest:testDeployment() (gas: 45769)
CreateCloneTokenTest:testGenerateTokens() (gas: 2045315)
CreateCloneTokenTest:testGenerateTokens() (gas: 2050854)
DestroyTokensTest:testDeployment() (gas: 45598)
DestroyTokensTest:testDestroyTokens() (gas: 124840)
DestroyTokensTest:testDestroyTokens() (gas: 124930)
GenerateTokensTest:testDeployment() (gas: 45553)
GenerateTokensTest:testGenerateTokens() (gas: 114564)
GenerateTokensTest:testGenerateTokens() (gas: 114609)
GenerateTokensTest:test_RevertWhen_SenderIsNotController() (gas: 14930)
MiniMeTokenTest:testDeployment() (gas: 45598)
ReentrancyTest:testAttack() (gas: 229331)
ReentrancyTest:testAttack() (gas: 229376)
TransferTest:testDeployment() (gas: 45814)
TransferTest:testTransfer() (gas: 201218)
TransferTest:testTransfer() (gas: 201263)

View File

@ -29,24 +29,18 @@ error ControllerNotSet();
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/// @title MiniMeToken Contract
import { Controlled } from "./Controlled.sol";
import { TokenController } from "./TokenController.sol";
import { ApproveAndCallFallBack } from "./ApproveAndCallFallBack.sol";
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
/// @title MiniMeBase Contract
/// @author Jordi Baylina
/// @dev This token contract's goal is to make it easy for anyone to clone this
/// 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
/// @dev It is ERC20 compliant, but still needs to under go further testing.
import { Controlled } from "./Controlled.sol";
import { TokenController } from "./TokenController.sol";
import { ApproveAndCallFallBack } from "./ApproveAndCallFallBack.sol";
import { MiniMeTokenFactory } from "./MiniMeTokenFactory.sol";
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
/// @dev The actual token contract, the default controller is the msg.sender
/// that deploys the contract, so usually this token will be deployed by a
/// token controller contract, which Giveth will call a "Campaign"
contract MiniMeToken is Controlled, IERC20 {
abstract contract MiniMeBase is Controlled, IERC20 {
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
@ -64,7 +58,7 @@ contract MiniMeToken is Controlled, IERC20 {
// `parentToken` is the Token address that was cloned to produce this token;
// it will be 0x0 for a token that was not cloned
MiniMeToken public immutable parentToken;
MiniMeBase public immutable parentToken;
// `parentSnapShotBlock` is the block number from the Parent Token that was
// used to determine the initial distribution of the Clone Token
@ -87,17 +81,7 @@ contract MiniMeToken is Controlled, IERC20 {
// Flag that determines if the token is transferable or not.
bool public transfersEnabled;
// The factory used to create new clone tokens
MiniMeTokenFactory public immutable tokenFactory;
////////////////
// Constructor
////////////////
/// @notice Constructor to create a MiniMeToken
/// @param _tokenFactory The address of the MiniMeTokenFactory contract that
/// will create the Clone token contracts, the token factory needs to be
/// deployed first
/// @notice Constructor to create a MiniMeBase
/// @param _parentToken Address of the parent token, set to 0x0 if it is a
/// new token
/// @param _parentSnapShotBlock Block of the parent token that will
@ -108,15 +92,13 @@ contract MiniMeToken is Controlled, IERC20 {
/// @param _tokenSymbol Token Symbol for the new token
/// @param _transfersEnabled If true, tokens will be able to be transferred
constructor(
MiniMeTokenFactory _tokenFactory,
MiniMeToken _parentToken,
MiniMeBase _parentToken,
uint256 _parentSnapShotBlock,
string memory _tokenName,
uint8 _decimalUnits,
string memory _tokenSymbol,
bool _transfersEnabled
) {
tokenFactory = _tokenFactory;
name = _tokenName; // Set the name
decimals = _decimalUnits; // Set the decimals
symbol = _tokenSymbol; // Set the symbol
@ -318,42 +300,6 @@ contract MiniMeToken is Controlled, IERC20 {
}
}
////////////////
// Clone Token Method
////////////////
/// @notice Creates a new clone token with the initial distribution being
/// this token at `_snapshotBlock`
/// @param _cloneTokenName Name of the clone token
/// @param _cloneDecimalUnits Number of decimals of the smallest unit
/// @param _cloneTokenSymbol Symbol of the clone token
/// @param _snapshotBlock Block when the distribution of the parent token is
/// copied to set the initial distribution of the new clone token;
/// if the block is zero than the actual block, the current block is used
/// @param _transfersEnabled True if transfers are allowed in the clone
/// @return The address of the new MiniMeToken Contract
function createCloneToken(
string memory _cloneTokenName,
uint8 _cloneDecimalUnits,
string memory _cloneTokenSymbol,
uint256 _snapshotBlock,
bool _transfersEnabled
)
public
returns (address)
{
if (_snapshotBlock == 0) _snapshotBlock = block.number;
MiniMeToken cloneToken = tokenFactory.createCloneToken(
this, _snapshotBlock, _cloneTokenName, _cloneDecimalUnits, _cloneTokenSymbol, _transfersEnabled
);
cloneToken.changeController(payable(msg.sender));
// An event to make the token easy to find on the blockchain
emit NewCloneToken(address(cloneToken), _snapshotBlock);
return address(cloneToken);
}
////////////////
// Generate and destroy tokens
////////////////
@ -362,7 +308,7 @@ contract MiniMeToken is Controlled, IERC20 {
/// @param _owner The address that will be assigned the new tokens
/// @param _amount The quantity of tokens generated
/// @return True if the tokens are generated correctly
function generateTokens(address _owner, uint256 _amount) public onlyController returns (bool) {
function mint(address _owner, uint256 _amount) internal returns (bool) {
uint256 curTotalSupply = totalSupply();
if (curTotalSupply + _amount < curTotalSupply) revert Overflow(); // Check for overflow
uint256 previousBalanceTo = balanceOf(_owner);
@ -377,7 +323,7 @@ contract MiniMeToken is Controlled, IERC20 {
/// @param _owner The address that will lose the tokens
/// @param _amount The quantity of tokens to burn
/// @return True if the tokens are burned correctly
function destroyTokens(address _owner, uint256 _amount) public onlyController returns (bool) {
function burn(address _owner, uint256 _amount) internal returns (bool) {
uint256 curTotalSupply = totalSupply();
if (curTotalSupply < _amount) revert NotEnoughSupply();
uint256 previousBalanceFrom = balanceOf(_owner);
@ -496,5 +442,4 @@ contract MiniMeToken is Controlled, IERC20 {
// Events
////////////////
event ClaimedTokens(address indexed _token, address indexed _controller, uint256 _amount);
event NewCloneToken(address indexed _cloneToken, uint256 _snapshotBlock);
}

99
contracts/MiniMeToken.sol Normal file
View File

@ -0,0 +1,99 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.0;
import { MiniMeBase } from "./MiniMeBase.sol";
import { MiniMeTokenFactory } from "./MiniMeTokenFactory.sol";
contract MiniMeToken is MiniMeBase {
// The factory used to create new clone tokens
MiniMeTokenFactory public immutable tokenFactory;
////////////////
// Constructor
////////////////
/// @notice Constructor to create a MiniMeToken
/// @param _tokenFactory The address of the MiniMeTokenFactory contract that
/// will create the Clone token contracts, the token factory needs to be
/// deployed first
/// @param _parentToken Address of the parent token, set to 0x0 if it is a
/// new token
/// @param _parentSnapShotBlock Block of the parent token that will
/// determine the initial distribution of the clone token, set to 0 if it
/// is a new token
/// @param _tokenName Name of the new token
/// @param _decimalUnits Number of decimals of the new token
/// @param _tokenSymbol Token Symbol for the new token
/// @param _transfersEnabled If true, tokens will be able to be transferred
constructor(
MiniMeTokenFactory _tokenFactory,
MiniMeToken _parentToken,
uint256 _parentSnapShotBlock,
string memory _tokenName,
uint8 _decimalUnits,
string memory _tokenSymbol,
bool _transfersEnabled
)
MiniMeBase(_parentToken, _parentSnapShotBlock, _tokenName, _decimalUnits, _tokenSymbol, _transfersEnabled)
{
tokenFactory = _tokenFactory;
}
////////////////
// Generate and destroy tokens
////////////////
/// @notice Generates `_amount` tokens that are assigned to `_owner`
/// @param _owner The address that will be assigned the new tokens
/// @param _amount The quantity of tokens generated
/// @return True if the tokens are generated correctly
function generateTokens(address _owner, uint256 _amount) public onlyController returns (bool) {
return mint(_owner, _amount);
}
/// @notice Burns `_amount` tokens from `_owner`
/// @param _owner The address that will lose the tokens
/// @param _amount The quantity of tokens to burn
/// @return True if the tokens are burned correctly
function destroyTokens(address _owner, uint256 _amount) public onlyController returns (bool) {
return burn(_owner, _amount);
}
////////////////
// Clone Token Method
////////////////
/// @notice Creates a new clone token with the initial distribution being
/// this token at `_snapshotBlock`
/// @param _cloneTokenName Name of the clone token
/// @param _cloneDecimalUnits Number of decimals of the smallest unit
/// @param _cloneTokenSymbol Symbol of the clone token
/// @param _snapshotBlock Block when the distribution of the parent token is
/// copied to set the initial distribution of the new clone token;
/// if the block is zero than the actual block, the current block is used
/// @param _transfersEnabled True if transfers are allowed in the clone
/// @return The address of the new MiniMeToken Contract
function createCloneToken(
string memory _cloneTokenName,
uint8 _cloneDecimalUnits,
string memory _cloneTokenSymbol,
uint256 _snapshotBlock,
bool _transfersEnabled
)
public
returns (address)
{
if (_snapshotBlock == 0) _snapshotBlock = block.number;
MiniMeToken cloneToken = tokenFactory.createCloneToken(
this, _snapshotBlock, _cloneTokenName, _cloneDecimalUnits, _cloneTokenSymbol, _transfersEnabled
);
cloneToken.changeController(payable(msg.sender));
// An event to make the token easy to find on the blockchain
emit NewCloneToken(address(cloneToken), _snapshotBlock);
return address(cloneToken);
}
event NewCloneToken(address indexed _cloneToken, uint256 _snapshotBlock);
}

View File

@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.0;
import "./MiniMeToken.sol";
import { MiniMeToken } from "./MiniMeToken.sol";
/// @title MiniMeToken Factory Contract
/// @dev This contract is used to generate clone contracts from a contract.