can someone help me out, I'm testing my buySingle function, by adding random values inside my first 3 inputs and an array in the last one. when I try executing I keep getting invalid proof. What I am supposed to be adding in the proof??
Currently, this is my _proof input:
[
"0x4406d4944cd8815a388db585f5a7a0b70d21ea3dd912414d4313136a2eac33a0",
"0x79fd2a4dca72d9577193fcc3d1ffd96ecf8127dab0bd295a48fcefa78c1ff948",
"0x6ec8df7eec81d5a31e79f9d3101bc2468ecf58af264968ba019766f12b2c6a65",
"0xb350ca80e5d4284caedb2d59caa85729952df9902c07f2d86054b05a4193551c",
"0xba0b16b6e0abae3d2a33a072dc7a0a59d77b1de708c5477e50634319f1496529",
"0x6c9b99e2e6f4aaaad0694375728a68e44160888e9fada56d440f4fbe3cbf33ea",
"0x17fb11285cd87a16370a061e2359f85d288f377f69248e7172c43475b7035806",
"0x33a63c21e96c9b7cc2081da21c9f2a0e8ff0904569a3acb17fa76129443dd047",
"0x266505b770c75759218c46c22f531ef5bd216c97246bf226567ddb753bfc93db",
"0x77e2eac49c0478daeac4f6023434ade425b8c45d4150d0d5a2c8cea8555027d2",
"0xe28a06c8328b5534e8de2adff61ee2916b040307a2165adab2cfd4b8eaa8fbfc",
"0x19a35f620df55ae0a87e54a8a1911bf9a40a5f41b54a1031f18a714c49e4ca17",
"0xd24be13d5d23f5102e312d8e5afd1b7dc5573b44e614c242d68d80899e10821f"
]
input:
price:
start:
end:
proof:
Output:
"message": "execution reverted: invalid proof"
and here is my code:
pragma solidity 0.8.10;
import "#openzeppelin/contracts/access/Ownable.sol";
import "#openzeppelin/contracts/utils/cryptography/MerkleProof.sol";
import "#openzeppelin/contracts/interfaces/IERC165.sol";
import "#openzeppelin/contracts/interfaces/IERC721.sol";
import "./IMintableERC721.sol";
contract MintablePresale is Ownable {
// Use Zeppelin MerkleProof Library to verify Merkle proofs
using MerkleProof for bytes32[];
uint32 public nextId = 1;
uint32 public finalId;
uint32 public batchLimit;
uint32 public mintLimit;
uint32 public soldCounter;
/**
* #notice Merkle tree root to validate (address, cost, startDate, endDate)
* tuples
*/
bytes32 public root;
uint256 public constant UID = 0x96156164645b31243986cb90a4oio09d99f140aa39d43ffa58a6af6d5e90bdbf4;
address public immutable tokenContract;
address public immutable developerAddress;
mapping(address => uint32) public mints;
/**
* #dev Fired in initialize()
*
* #param _by an address which executed the initialization
* #param _nextId next ID of the token to mint
* #param _finalId final ID of the token to mint
* #param _batchLimit how many tokens is allowed to buy in a single transaction
* #param _root merkle tree root
*/
event Initialized(
address indexed _by,
uint32 _nextId,
uint32 _finalId,
uint32 _batchLimit,
uint32 _limit,
bytes32 _root
);
event Bought(address indexed _by, address indexed _to, uint256 _amount, uint256 _value);
constructor(address _tokenContract, address _developerAddress) {
// verify the input is set
require(_tokenContract != address(0), "token contract is not set");
// verify input is valid smart contract of the expected interfaces
require(
IERC165(_tokenContract).supportsInterface(type(IMintableERC721).interfaceId)
&& IERC165(_tokenContract).supportsInterface(type(IMintableERC721).interfaceId),
"unexpected token contract type"
);
// assign the addresses
tokenContract = _tokenContract;
developerAddress = _developerAddress;
}
function itemsOnSale() public view returns(uint32) {
// calculate items left on sale, taking into account that
// finalId is on sale (inclusive bound)
return finalId > nextId? finalId + 1 - nextId: 0;
}
function itemsAvailable() public view returns(uint32) {
// delegate to itemsOnSale() if sale is active, return zero otherwise
return isActive() ? itemsOnSale(): 0;
}
function isActive() public view virtual returns(bool) {
// evaluate sale state based on the internal state variables and return
return nextId <= finalId;
}
/**
* #dev Restricted access function to set up sale parameters, all at once,
* or any subset of them
*
* #dev To skip parameter initialization, set it to `-1`,
* that is a maximum value for unsigned integer of the corresponding type;
* `_aliSource` and `_aliValue` must both be either set or skipped
*
* #dev Example: following initialization will update only _itemPrice and _batchLimit,
* leaving the rest of the fields unchanged
* initialize(
* 0xFFFFFFFF,
* 0xFFFFFFFF,
* 10,
* 0xFFFFFFFF
* )
*
* #dev Requires next ID to be greater than zero (strict): `_nextId > 0`
*
* #dev Requires transaction sender to have `ROLE_SALE_MANAGER` role
*
* #param _nextId next ID of the token to mint, will be increased
* in smart contract storage after every successful buy
* #param _finalId final ID of the token to mint; sale is capable of producing
* `_finalId - _nextId + 1` tokens
* when current time is within _saleStart (inclusive) and _saleEnd (exclusive)
* #param _batchLimit how many tokens is allowed to buy in a single transaction,
* set to zero to disable the limit
* #param _mintLimit how many tokens is allowed to buy for the duration of the sale,
* set to zero to disable the limit
* #param _root merkle tree root used to verify whether an address can mint
*/
function initialize(
uint32 _nextId, // <<<--- keep type in sync with the body type(uint32).max !!!
uint32 _finalId, // <<<--- keep type in sync with the body type(uint32).max !!!
uint32 _batchLimit, // <<<--- keep type in sync with the body type(uint32).max !!!
uint32 _mintLimit, // <<<--- keep type in sync with the body type(uint32).max !!!
bytes32 _root // <<<--- keep type in sync with the 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF !!!
) public onlyOwner {
// verify the inputs
require(_nextId > 0, "zero nextId");
// no need to verify extra parameters - "incorrect" values will deactivate the sale
// initialize contract state based on the values supplied
// take into account our convention that value `-1` means "do not set"
// 0xFFFFFFFFFFFFFFFF, 64 bits
// 0xFFFFFFFF, 32 bits
if(_nextId != type(uint32).max) {
nextId = _nextId;
}
// 0xFFFFFFFF, 32 bits
if(_finalId != type(uint32).max) {
finalId = _finalId;
}
// 0xFFFFFFFF, 32 bits
if(_batchLimit != type(uint32).max) {
batchLimit = _batchLimit;
}
// 0xFFFFFFFF, 32 bits
if(_mintLimit != type(uint32).max) {
mintLimit = _mintLimit;
}
// 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 256 bits
if(_root != 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) {
root = _root;
}
// emit an event - read values from the storage since not all of them might be set
emit Initialized(
msg.sender,
nextId,
finalId,
batchLimit,
mintLimit,
root
);
}
/**
* #notice Buys several (at least two) tokens in a batch.
* Accepts ETH as payment and mints a token
*
* #param _amount amount of tokens to create, two or more
*/
function buy(uint256 _price, uint256 _start, uint256 _end, bytes32[] memory _proof, uint32 _amount) public payable {
// delegate to `buyTo` with the transaction sender set to be a recipient
buyTo(msg.sender, _price, _start, _end, _proof, _amount);
}
/**
* #notice Buys several (at least two) tokens in a batch to an address specified.
* Accepts ETH as payment and mints tokens
*
* #param _to address to mint tokens to
* #param _amount amount of tokens to create, two or more
*/
function buyTo(address _to, uint256 _price, uint256 _start, uint256 _end, bytes32[] memory _proof, uint32 _amount) public payable {
// construct Merkle tree leaf from the inputs supplied
bytes32 leaf = keccak256(abi.encodePacked(msg.sender, _price, _start, _end));
// verify proof
require(_proof.verify(root, leaf), "invalid proof");
// verify the inputs
require(_to != address(0), "recipient not set");
require(_amount > 1 && (batchLimit == 0 || _amount <= batchLimit), "incorrect amount");
require(block.timestamp >= _start, "sale not yet started");
require(block.timestamp <= _end, "sale ended");
// verify mint limit
if(mintLimit != 0) {
require(mints[msg.sender] + _amount <= mintLimit, "mint limit reached");
}
// verify there is enough items available to buy the amount
// verifies sale is in active state under the hood
require(itemsAvailable() >= _amount, "inactive sale or not enough items available");
// calculate the total price required and validate the transaction value
uint256 totalPrice = _price * _amount;
require(msg.value >= totalPrice, "not enough funds");
// mint token to to the recipient
IMintableERC721(tokenContract).mintBatch(_to, nextId, _amount);
// increment `nextId`
nextId += _amount;
// increment `soldCounter`
soldCounter += _amount;
// increment sender mints
mints[msg.sender] += _amount;
// if ETH amount supplied exceeds the price
if(msg.value > totalPrice) {
// send excess amount back to sender
payable(msg.sender).transfer(msg.value - totalPrice);
}
// emit en event
emit Bought(msg.sender, _to, _amount, totalPrice);
}
/**
* #notice Buys single token.
* Accepts ETH as payment and mints a token
*/
function buySingle(uint256 _price, uint256 _start, uint256 _end, bytes32[] memory _proof) public payable {
// delegate to `buySingleTo` with the transaction sender set to be a recipient
buySingleTo(msg.sender, _price, _start, _end, _proof);
}
/**
* #notice Buys single token to an address specified.
* Accepts ETH as payment and mints a token
*
* #param _to address to mint token to
*/
function buySingleTo(address _to, uint256 _price, uint256 _start, uint256 _end, bytes32[] memory _proof) public payable {
// construct Merkle tree leaf from the inputs supplied
bytes32 leaf = keccak256(abi.encodePacked(msg.sender, _price, _start, _end));
// verify proof
require(_proof.verify(root, leaf), "invalid proof");
// verify the inputs and transaction value
require(_to != address(0), "recipient not set");
require(msg.value >= _price, "not enough funds");
require(block.timestamp >= _start, "sale not yet started");
require(block.timestamp <= _end, "sale ended");
// verify mint limit
if(mintLimit != 0) {
require(mints[msg.sender] + 1 <= mintLimit, "mint limit reached");
}
// verify sale is in active state
require(isActive(), "inactive sale");
// mint token to the recipient
IMintableERC721(tokenContract).mint(_to, nextId);
// increment `nextId`
nextId++;
// increment `soldCounter`
soldCounter++;
// increment sender mints
mints[msg.sender]++;
// emit en event
emit Bought(msg.sender, _to, 1, _price);
}
}
}
I found this on the open zeppelin website
https://forum.openzeppelin.com/t/what-to-provide-in-the-proof-parameter-of-the-verify-function-for-the-merkleproof-library/3111
but still do not understand how to get the hashes from the leaf to the root.
Here is my IMintableERC721 as requested in the comments
// SPDX-License-Identifier: MIT
pragma solidity 0.8.10;
interface IMintableERC721 {
/**
* #notice Checks if specified token exists
*
* #dev Returns whether the specified token ID has an ownership
* information associated with it
*
* #param _tokenId ID of the token to query existence for
* #return whether the token exists (true - exists, false - doesn't exist)
*/
function exists(uint256 _tokenId) external view returns(bool);
/**
* #dev Creates new token with token ID specified
* and assigns an ownership `_to` for this token
*
* #dev Unsafe: doesn't execute `onERC721Received` on the receiver.
* Prefer the use of `saveMint` instead of `mint`.
*
* #dev Should have a restricted access handled by the implementation
*
* #param _to an address to mint token to
* #param _tokenId ID of the token to mint
*/
function mint(address _to, uint256 _tokenId) external;
/**
* #dev Creates new tokens starting with token ID specified
* and assigns an ownership `_to` for these tokens
*
* #dev Token IDs to be minted: [_tokenId, _tokenId + n)
*
* #dev n must be greater or equal 2: `n > 1`
*
* #dev Unsafe: doesn't execute `onERC721Received` on the receiver.
* Prefer the use of `saveMintBatch` instead of `mintBatch`.
*
* #dev Should have a restricted access handled by the implementation
*
* #param _to an address to mint tokens to
* #param _tokenId ID of the first token to mint
* #param n how many tokens to mint, sequentially increasing the _tokenId
*/
function mintBatch(address _to, uint256 _tokenId, uint256 n) external;
/**
* #dev Creates new token with token ID specified
* and assigns an ownership `_to` for this token
*
* #dev Checks if `_to` is a smart contract (code size > 0). If so, it calls
* `onERC721Received` on `_to` and throws if the return value is not
* `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`.
*
* #dev Should have a restricted access handled by the implementation
*
* #param _to an address to mint token to
* #param _tokenId ID of the token to mint
*/
function safeMint(address _to, uint256 _tokenId) external;
/**
* #dev Creates new token with token ID specified
* and assigns an ownership `_to` for this token
*
* #dev Checks if `_to` is a smart contract (code size > 0). If so, it calls
* `onERC721Received` on `_to` and throws if the return value is not
* `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`.
*
* #dev Should have a restricted access handled by the implementation
*
* #param _to an address to mint token to
* #param _tokenId ID of the token to mint
* #param _data additional data with no specified format, sent in call to `_to`
*/
function safeMint(address _to, uint256 _tokenId, bytes memory _data) external;
/**
* #dev Creates new tokens starting with token ID specified
* and assigns an ownership `_to` for these tokens
*
* #dev Token IDs to be minted: [_tokenId, _tokenId + n)
*
* #dev n must be greater or equal 2: `n > 1`
*
* #dev Checks if `_to` is a smart contract (code size > 0). If so, it calls
* `onERC721Received` on `_to` and throws if the return value is not
* `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`.
*
* #dev Should have a restricted access handled by the implementation
*
* #param _to an address to mint token to
* #param _tokenId ID of the token to mint
* #param n how many tokens to mint, sequentially increasing the _tokenId
*/
function safeMintBatch(address _to, uint256 _tokenId, uint256 n) external;
/**
* #dev Creates new tokens starting with token ID specified
* and assigns an ownership `_to` for these tokens
*
* #dev Token IDs to be minted: [_tokenId, _tokenId + n)
*
* #dev n must be greater or equal 2: `n > 1`
*
* #dev Checks if `_to` is a smart contract (code size > 0). If so, it calls
* `onERC721Received` on `_to` and throws if the return value is not
* `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`.
*
* #dev Should have a restricted access handled by the implementation
*
* #param _to an address to mint token to
* #param _tokenId ID of the token to mint
* #param n how many tokens to mint, sequentially increasing the _tokenId
* #param _data additional data with no specified format, sent in call to `_to`
*/
function safeMintBatch(address _to, uint256 _tokenId, uint256 n, bytes memory _data) external;
}
Related
In the smart contract code below, there is a function being executed inside the constructor function. Can anyone please explain what is happening in the constructor?
pragma solidity 0.8.7;
import "../interfaces/IAbstractRewards.sol";
import "#openzeppelin/contracts/utils/math/SafeCast.sol";
/**
* #dev Based on: https://github.com/indexed-finance/dividends/blob/master/contracts/base/AbstractDividends.sol
* Renamed dividends to rewards.
* #dev (OLD) Many functions in this contract were taken from this repository:
* https://github.com/atpar/funds-distribution-token/blob/master/contracts/FundsDistributionToken.sol
* which is an example implementation of ERC 2222, the draft for which can be found at
* https://github.com/atpar/funds-distribution-token/blob/master/EIP-DRAFT.md
*
* This contract has been substantially modified from the original and does not comply with ERC 2222.
* Many functions were renamed as "rewards" rather than "funds" and the core functionality was separated
* into this abstract contract which can be inherited by anything tracking ownership of reward shares.
*/
abstract contract AbstractRewards is IAbstractRewards {
using SafeCast for uint128;
using SafeCast for uint256;
using SafeCast for int256;
/* ======== Constants ======== */
uint128 public constant POINTS_MULTIPLIER = type(uint128).max;
/* ======== Internal Function References ======== */
function(address) view returns (uint256) private immutable getSharesOf;
function() view returns (uint256) private immutable getTotalShares;
/* ======== Storage ======== */
uint256 public pointsPerShare;
mapping(address => int256) public pointsCorrection;
mapping(address => uint256) public withdrawnRewards;
constructor(
function(address) view returns (uint256) getSharesOf_,
function() view returns (uint256) getTotalShares_
) {
getSharesOf = getSharesOf_;
getTotalShares = getTotalShares_;
}
/* ======== Public View Functions ======== */
/**
* #dev Returns the total amount of rewards a given address is able to withdraw.
* #param _account Address of a reward recipient
* #return A uint256 representing the rewards `account` can withdraw
*/
function withdrawableRewardsOf(address _account) public view override returns (uint256) {
return cumulativeRewardsOf(_account) - withdrawnRewards[_account];
}
/**
* #notice View the amount of rewards that an address has withdrawn.
* #param _account The address of a token holder.
* #return The amount of rewards that `account` has withdrawn.
*/
function withdrawnRewardsOf(address _account) public view override returns (uint256) {
return withdrawnRewards[_account];
}
/**
* #notice View the amount of rewards that an address has earned in total.
* #dev accumulativeFundsOf(account) = withdrawableRewardsOf(account) + withdrawnRewardsOf(account)
* = (pointsPerShare * balanceOf(account) + pointsCorrection[account]) / POINTS_MULTIPLIER
* #param _account The address of a token holder.
* #return The amount of rewards that `account` has earned in total.
*/
function cumulativeRewardsOf(address _account) public view override returns (uint256) {
return ((pointsPerShare * getSharesOf(_account)).toInt256() + pointsCorrection[_account]).toUint256() / POINTS_MULTIPLIER;
}
/* ======== Dividend Utility Functions ======== */
/**
* #notice Distributes rewards to token holders.
* #dev It reverts if the total shares is 0.
* It emits the `RewardsDistributed` event if the amount to distribute is greater than 0.
* About undistributed rewards:
* In each distribution, there is a small amount which does not get distributed,
* which is `(amount * POINTS_MULTIPLIER) % totalShares()`.
* With a well-chosen `POINTS_MULTIPLIER`, the amount of funds that are not getting
* distributed in a distribution can be less than 1 (base unit).
*/
function _distributeRewards(uint256 _amount) internal {
uint256 shares = getTotalShares();
require(shares > 0, "AbstractRewards._distributeRewards: total share supply is zero");
if (_amount > 0) {
pointsPerShare = pointsPerShare + (_amount * POINTS_MULTIPLIER / shares);
emit RewardsDistributed(msg.sender, _amount);
}
}
/**
* #notice Prepares collection of owed rewards
* #dev It emits a `RewardsWithdrawn` event if the amount of withdrawn rewards is
* greater than 0.
*/
function _prepareCollect(address _account) internal returns (uint256) {
uint256 _withdrawableDividend = withdrawableRewardsOf(_account);
if (_withdrawableDividend > 0) {
withdrawnRewards[_account] = withdrawnRewards[_account] + _withdrawableDividend;
emit RewardsWithdrawn(_account, _withdrawableDividend);
}
return _withdrawableDividend;
}
function _correctPointsForTransfer(address _from, address _to, uint256 _shares) internal {
int256 _magCorrection = (pointsPerShare * _shares).toInt256();
pointsCorrection[_from] = pointsCorrection[_from] + _magCorrection;
pointsCorrection[_to] = pointsCorrection[_to] - _magCorrection;
}
/**
* #dev Increases or decreases the points correction for `account` by
* `shares*pointsPerShare`.
*/
function _correctPoints(address _account, int256 _shares) internal {
pointsCorrection[_account] = pointsCorrection[_account] + (_shares * (int256(pointsPerShare)));
}
}
Now, in the smart contract below (BasePool), it inherits the above AbstractRewards smart contract. In the constructor of the BasePool contract how is balanceOf and totalSupply being passed to the AbstractRewards contract?
abstract contract BasePool is ERC20Votes, AbstractRewards, IBasePool, TokenSaver {
using SafeERC20 for IERC20;
using SafeCast for uint256;
using SafeCast for int256;
IERC20 public immutable depositToken;
IERC20 public immutable rewardToken;
ITimeLockPool public immutable escrowPool;
uint256 public immutable escrowPortion; // how much is escrowed 1e18 == 100%
uint256 public immutable escrowDuration; // escrow duration in seconds
event RewardsClaimed(address indexed _from, address indexed _receiver, uint256 _escrowedAmount, uint256 _nonEscrowedAmount);
constructor(
string memory _name,
string memory _symbol,
address _depositToken,
address _rewardToken,
address _escrowPool,
uint256 _escrowPortion,
uint256 _escrowDuration
) ERC20Permit(_name) ERC20(_name, _symbol) AbstractRewards(balanceOf, totalSupply) {
require(_escrowPortion <= 1e18, "BasePool.constructor: Cannot escrow more than 100%");
require(_depositToken != address(0), "BasePool.constructor: Deposit token must be set");
depositToken = IERC20(_depositToken);
rewardToken = IERC20(_rewardToken);
escrowPool = ITimeLockPool(_escrowPool);
escrowPortion = _escrowPortion;
escrowDuration = _escrowDuration;
if(_rewardToken != address(0) && _escrowPool != address(0)) {
IERC20(_rewardToken).safeApprove(_escrowPool, type(uint256).max);
}
}
function _mint(address _account, uint256 _amount) internal virtual override {
super._mint(_account, _amount);
_correctPoints(_account, -(_amount.toInt256()));
}
function _burn(address _account, uint256 _amount) internal virtual override {
super._burn(_account, _amount);
_correctPoints(_account, _amount.toInt256());
}
function _transfer(address _from, address _to, uint256 _value) internal virtual override {
super._transfer(_from, _to, _value);
_correctPointsForTransfer(_from, _to, _value);
}
function distributeRewards(uint256 _amount) external override {
rewardToken.safeTransferFrom(_msgSender(), address(this), _amount);
_distributeRewards(_amount);
}
function claimRewards(address _receiver) external {
uint256 rewardAmount = _prepareCollect(_msgSender());
uint256 escrowedRewardAmount = rewardAmount * escrowPortion / 1e18;
uint256 nonEscrowedRewardAmount = rewardAmount - escrowedRewardAmount;
if(escrowedRewardAmount != 0 && address(escrowPool) != address(0)) {
escrowPool.deposit(escrowedRewardAmount, escrowDuration, _receiver);
}
// ignore dust
if(nonEscrowedRewardAmount > 1) {
rewardToken.safeTransfer(_receiver, nonEscrowedRewardAmount);
}
emit RewardsClaimed(_msgSender(), _receiver, escrowedRewardAmount, nonEscrowedRewardAmount);
}
}
Constructor is a function to run at first, when smart contract is deploied and call.
If constructor has a prameter, you have to set them.
And if prameter include other smart contract's addresses, it have to be deploied before.
I have been working on a smart contract for a cryptocurrency over the past few hours and was getting ready to compile it. But when it was time to compile it, I got a error from Solidity stating: " ParserError: Expected pragma, import directive or contract/interface/library definition." It's on the final line, and I've checked the whole code multiple times to see no error. Any help would be great. Code is below:
pragma solidity ^0.4.21;
// File: zepplin-solidity/contracts/ownership/Ownable.sol
contract Ownable {
address public owner;
event OwnershipTransferred(address indexed previousOwner,
address indexed newOwner);
// #dev The Ownable constructor sets the original 'owner' of the contract to the sender
// account.
function Ownable() public {
owner = msg.sender;
}
// if any other account besides owner
modifier onlyOwner() {
requir(msg.sender == owner);
_;
}
// to transfer ownership in case of event
function transferOwnership(address newOwner) public onlyOwner
{
require(newOwner != address(0));
OwnershipTransferred(owner, newOwner);
owner = newOwner;
}
}
// Safemath protocol
library SafeMath {
function mul(uint256 a, uint256 b) internal pure returns
(uint256) {
if (a == 0) {
return 0;
}
uint256 c = a * b;
assert(c / a == b);
return c;
}
function div(uint256 a, uint256 b) internal pure returns
(uint256) {
// assrt(b > 0); // Solidity automatically throws when dividing by 0
uint256 c = a / b;
// assert(a == b * c + a % b); // There is no case in which this doesn't hold
return c;
}
function sub(unit256 a, uint256 b) internal pure returns
(uint256) {
assert(b <= a);
return a - b;
}
function add(uint256 a, uint256 b) internal pure returns
(uint256) {
uint256 c = a + b;
assert(c >= a);
return c;
}
}
// Smart contract title (ERC20)
contract ERC20 {
uint256 public totalSupply;
function balanceOf(address who) public view returns (uint256);
function transfer (address to, uint256 value) public returns (bool);
function allowance(address owner, address spender) public view returns (uint256);
function transferFrom(addres from, address to, uint256 value) public returns (bool);
function approve(address spender, uint256 value) public returns (bool);
event Transfer(address indexed from, address indexed to, uint256 value);
event approval(address indexed owner, address indexed spender, uint256 value);
}
contract HepburnA is ERC20, Ownable {
using SafeMath for uint256;
// the controller of minting and destroying tokens
address public hepburnDevmoon =
0x471E918a75A99038856eF9754368Eb1b5D15f9D5;
// the controller of approving of minting and withdraw tokens
address public hepburnCommunitymoon =
0x0554c3CF2315FB98181d1FEBfaf083cDf68Fa145;
struct TokensWithLock{
uint256 value;
uint256 blockNumber;
}
//Balances (shared with ERC20Basic replicant)
mapping(address => uint256) balances;
//When token numbers is less than incoming block
mapping(address => TokenswithLock) lockTokens;
mapping(address => mapping (address => uint256)) allowed;
// Token Cap
uint256 public totalSupplyCap = 1e11;
// Token Info
string public name = "Hepburn A";
string public symbol = "AUYHA";
uint8 public decimals = 18;
bool public mintingFinished = false;
// the block number when deploy
uint256 public deployBlockNumber = getCurrentBlockNumber();
// the min threshold of lock time
uint256 public constant TIMETHRESHOLD = 9720;
// the time when mintTokensWithinTime can be called
uint256 public constant MINTTIME = 291600;
// the lock time of minted tokens
uint256 public durationOfLock = 9720;
// True if transfers are allowed
bool public transferable = false;
// True if the transferable can be change
bool public canSetTransferable = true;
modifier canMint() {
require(!mintingFinished);
_;
}
modifier only(address _address) {
require(msg.sender == _address);
_;
}
modifier nonZeroAddress(address _address) {
require(_address != address(0));
_;
}
modifier canTransfer() {
require(transferable == true);
}
event SetDurationOfLock(address indexed _caller);
event ApproveMintTokens(address indexed _owner, uint256 _amount);
event WithdrawMintTokens(address indexed _owner, uint256 _amount);
event MintTokens(address indexed _owner, uint256 _amount);
event BurnTokens(address indexed _owner, uint256 _amount);
event MintFinished(address indexed _caller);
event setTransferable(address indexed _address, bool _transferable);
event SethepburnDevmoon(address indexed _old, address indexed _new);
event DisableSetTransferable(ddress indexed _address, bool _canSetTransferable);
function transfer(address _to, uint256 _value) canTransfer public returns (bool) {
require(_to != address(0));
require(_value <= balances[msg.sender]);
// SafeMath.sub will throw if there is not enough balance.
balances[msg.sender] = balances[msg.sender].sub(_value);
balances[_to] = balances[_to].add(_value);
Transfer(msg.sender, _to, _value);
return true;
}
/**
* #dev Gets the balance of the specified address.
* #param _owner The address to query the the balance of.
* #return An uint256 representing the amount owned by the passed address.
*/
function balanceOf(address _owner) public view returns (uint256 balance)
{
return balances[_owner];
}
/**
* #dev Transfer tokens from one address to another
* #param _from address The address which you want to send tokens from
* #param _to address The address which you want to transfer to
* #param _value uint256 the amount of tokens to be transferred
*/
function transferFrom(address _from, address _to, uint256 _value) canTransfer public returns (bool) {
require(_to != address(0));
require(_value <= balances[_from]);
require(_value <= allowed[_from][msg.sender]);
balances[_from] = balances[_from].sub(_value);
balances[_to] = balances[_to].add(_value);
allowed[_from][msg.sender] = allowed[_from][msg.sender].sub(_value);
Transfer(_from, _to, _value);
return true;
}
/**
* #dev Approve the passed address to spend the specified amount of tokens on behalf of msg.sender.
*
* Beware that changing an allowance with this method brings the risk that someone may use both the old
* and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this
* race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
* #param _spender The address which will spend the funds.
* #param _value The amount of tokens to be spent.
*/
function approve(address _spender, uint256 _value) canTransfer public returns (bool) {
allowed[msg.sender][_spender] = _value;
Approval(msg.sender, _spender, _value);
return true;
}
/**
* #dev Function to check the amount of tokens that an owner allowed to a spender.
* #param _owner address The address which owns the funds.
* #param _spender address The address which will spend the funds.
* #return A uint256 specifying the amount of tokens still available for the spender.
*/
function allowance(address _owner, address _spender) public view returns (uint256) {
return allowed[_owner][_spender];
}
/**
* approve should be called when allowed[_spender] == 0. To increment
* allowed value is better to use this function to avoid 2 calls (and wait until
* the first transaction is mined)
* From MonolithDAO Token.sol
*/
function increaseApproval(address _spender, uint256 _addedValue) canTransfer public returns (bool) {
allowed[msg.sender][_spender] = allowed[msg.sender][_spender].add(_addedValue);
Approval(msg.sender, _spender, allowed[msg.sender][_spender]);
return true;
}
function decreaseApproval(address _spender, uint256 _subtractedValue) canTransfer public returns (bool) {
uint256 oldValue = allowed[msg.sender][_spender];
if (_subtractedValue > oldValue) {
allowed[msg.sender][_spender] = 0;
} else {
allowed[msg.sender][_spender] = oldValue.sub(_subtractedValue);
}
Approval(msg.sender, _spender, allowed[msg.sender][_spender]);
return true;
}
/**
* #dev Enables token holders to transfer their tokens freely if true
* #param _transferable True if transfers are allowed
*/
function setTransferable(bool _transferable) only(hepburnDevmoon) public {
require(canSetTransferable == true);
transferable = _transferable;
SetTransferable(msg.sender, _transferable);
}
/**
* #dev disable the canSetTransferable
*/
function disableSetTransferable() only(hepburnDevmoon) public {
transferable = true;
canSetTransferable = false;
DisableSetTransferable(msg.sender, false);
}
/**
* #dev Set the hepburnDevmoon
* #param _hepburnDevmoon The new hepburnDevmoon
*/
function SethepburnDevmoon(address _hepburnDevmoon) only(hepburnDevmoon) nonZeroAddress(_hepburnDevmoon) public {
hepburnDevmoon = _hepburnDevmoon;
SethepburnDevmoon(msg.sender, _hepburnDevmoon);
}
/**
* #dev Set the hepburnCommunitymoon
* #param _hepburnCommunitymoon The new hepburnCommunitymoon
*/
function sethepburnCommunitymoon(address _hepburnCommunitymoon) only(hepburnCommunitymoon) nonZeroAddress(_hepburnCommunitymoon) public {
hepburnCommunitymoon = _hepburnCommunitymoon;
sethepburnCommunitymoon(msg.sender, _hepburnCommunitymoon);
}
/**
* #dev Set the duration of lock of tokens approved of minting
* #param _durationOfLock the new duration of lock
*/
function setDurationOfLock(uint256 _durationOfLock) canMint only(hepburnCommunitymoon) public {
require(_durationOfLock >= TIMETHRESHOLD);
durationOfLock = _durationOfLock;
SetDurationOfLock(msg.sender);
}
/**
* #dev Get the quantity of locked tokens
* #param _owner The address of locked tokens
* #return the quantity and the lock time of locked tokens
*/
function getLockTokens(address _owner) nonZeroAddress(_owner) view public returns (uint256 value, uint256 blockNumber) {
return (lockTokens[_owner].value, lockTokens[_owner].blockNumber);
}
/**
* #dev Approve of minting `_amount` tokens that are assigned to `_owner`
* #param _owner The address that will be assigned the new tokens
* #param _amount The quantity of tokens approved of mintting
* #return True if the tokens are approved of mintting correctly
*/
function approveMintTokens(address _owner, uint256 _amount) nonZeroAddress(_owner) canMint only(hepburnCommunitymoon) public returns (bool) {
require(_amount > 0);
uint256 previousLockTokens = lockTokens[_owner].value;
require(previousLockTokens + _amount >= previousLockTokens);
uint256 curTotalSupply = totalSupply;
require(curTotalSupply + _amount >= curTotalSupply); // Check for overflow
require(curTotalSupply + _amount <= totalSupplyCap); // Check for overflow of total supply cap
uint256 previousBalanceTo = balanceOf(_owner);
require(previousBalanceTo + _amount >= previousBalanceTo); // Check for overflow
lockTokens[_owner].value = previousLockTokens.add(_amount);
uint256 curBlockNumber = getCurrentBlockNumber();
lockTokens[_owner].blockNumber = curBlockNumber.add(durationOfLock);
ApproveMintTokens(_owner, _amount);
return true;
}
/**
* #dev Withdraw approval of minting `_amount` tokens that are assigned to `_owner`
* #param _owner The address that will be withdrawn the tokens
* #param _amount The quantity of tokens withdrawn approval of mintting
* #return True if the tokens are withdrawn correctly
*/
function withdrawMintTokens(address _owner, uint256 _amount) nonZeroAddress(_owner) canMint only(hepburnCommunitymoon) public returns (bool) {
require(_amount > 0);
uint256 previousLockTokens = lockTokens[_owner].value;
require(previousLockTokens - _amount >= 0);
lockTokens[_owner].value = previousLockTokens.sub(_amount);
if (previousLockTokens - _amount == 0) {
lockTokens[_owner].blockNumber = 0;
}
WithdrawMintTokens(_owner, _amount);
return true;
}
/**
* #dev Mints `_amount` tokens that are assigned to `_owner`
* #param _owner The address that will be assigned the new tokens
* #return True if the tokens are minted correctly
*/
function mintTokens(address _owner) canMint only(hepburnDevmoon) nonZeroAddress(_owner) public returns (bool) {
require(lockTokens[_owner].blockNumber <= getCurrentBlockNumber());
uint256 _amount = lockTokens[_owner].value;
uint256 curTotalSupply = totalSupply;
require(curTotalSupply + _amount >= curTotalSupply); // Check for overflow
require(curTotalSupply + _amount <= totalSupplyCap); // Check for overflow of total supply cap
uint256 previousBalanceTo = balanceOf(_owner);
require(previousBalanceTo + _amount >= previousBalanceTo); // Check for overflow
totalSupply = curTotalSupply.add(_amount);
balances[_owner] = previousBalanceTo.add(_amount);
lockTokens[_owner].value = 0;
lockTokens[_owner].blockNumber = 0;
MintTokens(_owner, _amount);
Transfer(0, _owner, _amount);
return true;
}
/**
* #dev Mints `_amount` tokens that are assigned to `_owner` within one day after deployment
* the tokens minted will be added to balance immediately
* #param _owner The address that will be assigned the new tokens
* #param _amount The quantity of tokens withdrawn minted
* #return True if the tokens are minted correctly
*/
function mintTokensWithinTime(address _owner, uint256 _amount) nonZeroAddress(_owner) canMint only(hepburnDevmoon) public returns (bool) {
require(_amount > 0);
require(getCurrentBlockNumber() < (deployBlockNumber + MINTTIME));
uint256 curTotalSupply = totalSupply;
require(curTotalSupply + _amount >= curTotalSupply); // Check for overflow
require(curTotalSupply + _amount <= totalSupplyCap); // Check for overflow of total supply cap
uint256 previousBalanceTo = balanceOf(_owner);
require(previousBalanceTo + _amount >= previousBalanceTo); // Check for overflow
totalSupply = curTotalSupply.add(_amount);
balances[_owner] = previousBalanceTo.add(_amount);
MintTokens(_owner, _amount);
Transfer(0, _owner, _amount);
return true;
}
/**
* #dev Transfer tokens to multiple addresses
* #param _addresses The addresses that will receieve tokens
* #param _amounts The quantity of tokens that will be transferred
* #return True if the tokens are transferred correctly
*/
function transferForMultiAddresses(address[] _addresses, uint256[] _amounts) canTransfer public returns (bool) {
for (uint256 i = 0; i < _addresses.length; i++) {
require(_addresses[i] != address(0));
require(_amounts[i] <= balances[msg.sender]);
require(_amounts[i] > 0);
// SafeMath.sub will throw if there is not enough balance.
balances[msg.sender] = balances[msg.sender].sub(_amounts[i]);
balances[_addresses[i]] = balances[_addresses[i]].add(_amounts[i]);
Transfer(msg.sender, _addresses[i], _amounts[i]);
}
return true;
}
/**
* #dev Burns `_amount` tokens from `_owner`
* #param _amount The quantity of tokens being burned
* #return True if the tokens are burned correctly
*/
function burnTokens(uint256 _amount) public returns (bool) {
require(_amount > 0);
uint256 curTotalSupply = totalSupply;
require(curTotalSupply >= _amount);
uint256 previousBalanceTo = balanceOf(msg.sender);
require(previousBalanceTo >= _amount);
totalSupply = curTotalSupply.sub(_amount);
balances[msg.sender] = previousBalanceTo.sub(_amount);
BurnTokens(msg.sender, _amount);
Transfer(msg.sender, 0, _amount);
return true;
}
/**
* #dev Function to stop minting new tokens.
* #return True if the operation was successful.
*/
function finishMinting() only(hepburnDevmoon) canMint public returns (bool) {
mintingFinished = true;
MintFinished(msg.sender);
return true;
}
function getCurrentBlockNumber() private view returns (uint256) {
return block.number;
}
}
}
}
You have two extra right curly brackets (}) at the end of the code. I think that is why you get the error.
Some Observations:
two extra right curly brackets at the end.
in modifier onlyOwner(), their is typo (requir -> require).
function sub(unit256 a) typo, (unit256 -> uint256).
address typo -> event DisableSetTransferable(ddress indexed _address,
bool _canSetTransferable);
function transferFrom(addres from) typo, (addres -> address).
modifier canTransfer() should contain "_;".
function setTransferable -> try changing name of this function as it
is same as the event name you are calling from inside. (and may be due
to prefix "set" in function name compiler can give error)
best practice if you call any function, call it with same name and
same case
(ex. approval not as Approval)
Call correct method SethepburnDevmoon not sethepburnCommunitymoon
inside function sethepburnCommunitymoon.
whenever you invoking any event, you should invoke it by adding prefix
"emit" to it.
The GAS used by this contract at deployment will be almost 3800000 ->
0.07562 eth -> almost $210 (in case you wanna know) -happy coding :)
I am creating a Smart Contract (BEP20 token) based on the BEP20Token template (https://github.com/binance-chain/bsc-genesis-contract/blob/master/contracts/bep20_template/BEP20Token.template).
The public contructor was modified to add some token details. However all of the standard functions are giving compile time issues like Overriding function is missing.
** here is the source code **
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.2;
interface IBEP20 {
/**
* #dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* #dev Returns the token decimals.
*/
function decimals() external view returns (uint8);
/**
* #dev Returns the token symbol.
*/
function symbol() external view returns (string memory);
/**
* #dev Returns the token name.
*/
function name() external view returns (string memory);
/**
* #dev Returns the bep token owner.
*/
function getOwner() external view returns (address);
/**
* #dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* #dev Moves `amount` tokens from the caller's account to `recipient`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address recipient, uint256 amount) external returns (bool);
/**
* #dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address _owner, address spender) external view returns (uint256);
/**
* #dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* #dev Moves `amount` tokens from `sender` to `recipient` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
/**
* #dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* #dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
}
/*
* #dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with GSN meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
contract Context {
// Empty internal constructor, to prevent people from mistakenly deploying
// an instance of this contract, which should be used via inheritance.
constructor () internal { }
function _msgSender() internal view returns (address payable) {
return msg.sender;
}
function _msgData() internal view returns (bytes memory) {
this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
return msg.data;
}
}
/**
* #dev Wrappers over Solidity's arithmetic operations with added overflow
* checks.
*
* Arithmetic operations in Solidity wrap on overflow. This can easily result
* in bugs, because programmers usually assume that an overflow raises an
* error, which is the standard behavior in high level programming languages.
* `SafeMath` restores this intuition by reverting the transaction when an
* operation overflows.
*
* Using this library instead of the unchecked operations eliminates an entire
* class of bugs, so it's recommended to use it always.
*/
library SafeMath {
/**
* #dev Returns the addition of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `+` operator.
*
* Requirements:
* - Addition cannot overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a, "SafeMath: addition overflow");
return c;
}
/**
* #dev Returns the subtraction of two unsigned integers, reverting on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
return sub(a, b, "SafeMath: subtraction overflow");
}
/**
* #dev Returns the subtraction of two unsigned integers, reverting with custom message on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b <= a, errorMessage);
uint256 c = a - b;
return c;
}
/**
* #dev Returns the multiplication of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `*` operator.
*
* Requirements:
* - Multiplication cannot overflow.
*/
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
if (a == 0) {
return 0;
}
uint256 c = a * b;
require(c / a == b, "SafeMath: multiplication overflow");
return c;
}
/**
* #dev Returns the integer division of two unsigned integers. Reverts on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
return div(a, b, "SafeMath: division by zero");
}
/**
* #dev Returns the integer division of two unsigned integers. Reverts with custom message on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
// Solidity only automatically asserts when dividing by 0
require(b > 0, errorMessage);
uint256 c = a / b;
// assert(a == b * c + a % b); // There is no case in which this doesn't hold
return c;
}
/**
* #dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* Reverts when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
* - The divisor cannot be zero.
*/
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
return mod(a, b, "SafeMath: modulo by zero");
}
/**
* #dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* Reverts with custom message when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
* - The divisor cannot be zero.
*/
function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b != 0, errorMessage);
return a % b;
}
}
/**
* #dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* By default, the owner account will be the one that deploys the contract. This
* can later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* #dev Initializes the contract setting the deployer as the initial owner.
*/
constructor () internal {
address msgSender = _msgSender();
_owner = msgSender;
emit OwnershipTransferred(address(0), msgSender);
}
/**
* #dev Returns the address of the current owner.
*/
function owner() public view returns (address) {
return _owner;
}
/**
* #dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
require(_owner == _msgSender(), "Ownable: caller is not the owner");
_;
}
/**
* #dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions anymore. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby removing any functionality that is only available to the owner.
*/
function renounceOwnership() public onlyOwner {
emit OwnershipTransferred(_owner, address(0));
_owner = address(0);
}
/**
* #dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public onlyOwner {
_transferOwnership(newOwner);
}
/**
* #dev Transfers ownership of the contract to a new account (`newOwner`).
*/
function _transferOwnership(address newOwner) internal {
require(newOwner != address(0), "Ownable: new owner is the zero address");
emit OwnershipTransferred(_owner, newOwner);
_owner = newOwner;
}
}
contract BEP20Token is Context, IBEP20, Ownable {
using SafeMath for uint256;
mapping (address => uint256) private _balances;
mapping (address => mapping (address => uint256)) private _allowances;
uint256 private _totalSupply;
uint8 private _decimals;
string private _symbol;
string private _name;
constructor() public {
_name = "Money Paiger Coin";
_symbol = "MPTT";
_decimals = 18;
_totalSupply = 10000000 * 10 ** 18; //10 million Total Supply
_balances[msg.sender] = _totalSupply;
emit Transfer(address(0), msg.sender, _totalSupply);
}
/**
* #dev Returns the bep token owner.
*/
function getOwner() external view returns (address) {
return owner();
}
/**
* #dev Returns the token decimals.
*/
function decimals() external view returns (uint8) {
return _decimals;
}
/**
* #dev Returns the token symbol.
*/
function symbol() external view returns (string memory) {
return _symbol;
}
/**
* #dev Returns the token name.
*/
function name() external view returns (string memory) {
return _name;
}
/**
* #dev See {BEP20-totalSupply}.
*/
function totalSupply() external view returns (uint256) {
return _totalSupply;
}
/**
* #dev See {BEP20-balanceOf}.
*/
function balanceOf(address account) external view returns (uint256) {
return _balances[account];
}
/**
* #dev See {BEP20-transfer}.
*
* Requirements:
*
* - `recipient` cannot be the zero address.
* - the caller must have a balance of at least `amount`.
*/
function transfer(address recipient, uint256 amount) external returns (bool) {
_transfer(_msgSender(), recipient, amount);
return true;
}
/**
* #dev See {BEP20-allowance}.
*/
function allowance(address owner, address spender) external view returns (uint256) {
return _allowances[owner][spender];
}
/**
* #dev See {BEP20-approve}.
*
* Requirements:
*
* - `spender` cannot be the zero address.
*/
function approve(address spender, uint256 amount) external returns (bool) {
_approve(_msgSender(), spender, amount);
return true;
}
/**
* #dev See {BEP20-transferFrom}.
*
* Emits an {Approval} event indicating the updated allowance. This is not
* required by the EIP. See the note at the beginning of {BEP20};
*
* Requirements:
* - `sender` and `recipient` cannot be the zero address.
* - `sender` must have a balance of at least `amount`.
* - the caller must have allowance for `sender`'s tokens of at least
* `amount`.
*/
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool) {
_transfer(sender, recipient, amount);
_approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "BEP20: transfer amount exceeds allowance"));
return true;
}
/**
* #dev Atomically increases the allowance granted to `spender` by the caller.
*
* This is an alternative to {approve} that can be used as a mitigation for
* problems described in {BEP20-approve}.
*
* Emits an {Approval} event indicating the updated allowance.
*
* Requirements:
*
* - `spender` cannot be the zero address.
*/
function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {
_approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));
return true;
}
/**
* #dev Atomically decreases the allowance granted to `spender` by the caller.
*
* This is an alternative to {approve} that can be used as a mitigation for
* problems described in {BEP20-approve}.
*
* Emits an {Approval} event indicating the updated allowance.
*
* Requirements:
*
* - `spender` cannot be the zero address.
* - `spender` must have allowance for the caller of at least
* `subtractedValue`.
*/
function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {
_approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, "BEP20: decreased allowance below zero"));
return true;
}
/**
* #dev Creates `amount` tokens and assigns them to `msg.sender`, increasing
* the total supply.
*
* Requirements
*
* - `msg.sender` must be the token owner
*/
function mint(uint256 amount) public onlyOwner returns (bool) {
_mint(_msgSender(), amount);
return true;
}
/**
* #dev Moves tokens `amount` from `sender` to `recipient`.
*
* This is internal function is equivalent to {transfer}, and can be used to
* e.g. implement automatic token fees, slashing mechanisms, etc.
*
* Emits a {Transfer} event.
*
* Requirements:
*
* - `sender` cannot be the zero address.
* - `recipient` cannot be the zero address.
* - `sender` must have a balance of at least `amount`.
*/
function _transfer(address sender, address recipient, uint256 amount) internal {
require(sender != address(0), "BEP20: transfer from the zero address");
require(recipient != address(0), "BEP20: transfer to the zero address");
_balances[sender] = _balances[sender].sub(amount, "BEP20: transfer amount exceeds balance");
_balances[recipient] = _balances[recipient].add(amount);
emit Transfer(sender, recipient, amount);
}
/** #dev Creates `amount` tokens and assigns them to `account`, increasing
* the total supply.
*
* Emits a {Transfer} event with `from` set to the zero address.
*
* Requirements
*
* - `to` cannot be the zero address.
*/
function _mint(address account, uint256 amount) internal {
require(account != address(0), "BEP20: mint to the zero address");
_totalSupply = _totalSupply.add(amount);
_balances[account] = _balances[account].add(amount);
emit Transfer(address(0), account, amount);
}
/**
* #dev Destroys `amount` tokens from `account`, reducing the
* total supply.
*
* Emits a {Transfer} event with `to` set to the zero address.
*
* Requirements
*
* - `account` cannot be the zero address.
* - `account` must have at least `amount` tokens.
*/
function _burn(address account, uint256 amount) internal {
require(account != address(0), "BEP20: burn from the zero address");
_balances[account] = _balances[account].sub(amount, "BEP20: burn amount exceeds balance");
_totalSupply = _totalSupply.sub(amount);
emit Transfer(account, address(0), amount);
}
/**
* #dev Sets `amount` as the allowance of `spender` over the `owner`s tokens.
*
* This is internal function is equivalent to `approve`, and can be used to
* e.g. set automatic allowances for certain subsystems, etc.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `owner` cannot be the zero address.
* - `spender` cannot be the zero address.
*/
function _approve(address owner, address spender, uint256 amount) internal {
require(owner != address(0), "BEP20: approve from the zero address");
require(spender != address(0), "BEP20: approve to the zero address");
_allowances[owner][spender] = amount;
emit Approval(owner, spender, amount);
}
/**
* #dev Destroys `amount` tokens from `account`.`amount` is then deducted
* from the caller's allowance.
*
* See {_burn} and {_approve}.
*/
function _burnFrom(address account, uint256 amount) internal {
_burn(account, amount);
_approve(account, _msgSender(), _allowances[account][_msgSender()].sub(amount, "BEP20: burn amount exceeds allowance"));
}
}
Couple of issues
Constructor public () - Warning: Visibility for constructor is ignored. If you want the contract to be non-deployable, making it "abstract" is sufficient.
function getOwner() - TypeError: Overriding function is missing "override" specifier. --> MoneyPaigerToken.sol:365:3: | 365 | function getOwner
Not sure what is missing here.
Regards
Sam
Constructor public () - Warning: Visibility for constructor is ignored. If you want the contract to be non-deployable, making it "abstract" is sufficient.
The warning message says it all. You can safely remove the public visibility modifier because it's ignored anyway.
If you marked the BEP20Token contract abstract, you would need to have a child contract inheriting from it, could not deploy the BEP20Token itself, but would have to deploy the child contract. Which is not what you want in this case.
constructor() { // remove the `public` modifier
function getOwner() - TypeError: Overriding function is missing "override" specifier. --> MoneyPaigerToken.sol:365:3: | 365 | function getOwner
Using interfaces in Solidity is not the same as in most other languages. Using expressions from other languages, there's no keyword for implements (an interface). There's just extends (a parent class) - in Solidity called simply is (a child of a class).
Interfaces are mostly used when you're interacting with other contracts (deployed on a different address). Example:
function getOtherTokenDecimals(address tokenAddress) external returns (uint8) {
IBEP20 tokenInstance = IBEP20(tokenAddress);
return tokenInstance.decimals();
}
As I wrote earlier, there's currently no expression for a contract implementing an interface. Just for extending a class. So your BEP20Token is IBEP20 extends the (interface) class and because the function getOwner() is already defined in the parent, you need to explicitly state that you want to override by using the override modifier.
function getOwner() external override view returns (address) { // add the `override` modifier
However, my approach instead of explicitly overriding the functions would be to move the events definitions to your BEP20Token, remove the interface definition and its inheritance because it's not used anywhere else in the code.
contract BEP20Token is Context, Ownable { // remove the `IBEP20` inheritance
// move the event definitions here
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
You can also remove the Context from the list of BEP20Token parents, because Ownable is also inheriting from Context.
contract BEP20Token is Ownable { // remove the `Context` parent
As mentioned in the error, you have to explicitly override the function in the child contract using the 'override' modifier.
function getOwner() override external view returns (address);
And subsequently make the function you want to override in the parent contract virtual by adding 'virtual' modifier.
So I am using a combination of Openzepplin solidity contracts to create a burnable token with a supply cap of 3million.
I keep getting the above error on the last contract and I have no idea why. I have tried replacing balanceOf[msg.sender] with balances[msg.sender], totalSupply_ with totalSupply, and re-declaring the existence of a public uint256 in the local contract (despite the fact that it should be inherited.
The following is my flattened contract with all dependencies (thanks for your help!):
pragma solidity ^0.4.24;
// File: contracts\token\ERC20\ERC20.sol
/**
* #title ERC20 interface
* #dev see https://github.com/ethereum/EIPs/issues/20
*/
contract ERC20 {
function totalSupply() public view returns (uint256);
function balanceOf(address _who) public view returns (uint256);
function allowance(address _owner, address _spender)
public view returns (uint256);
function transfer(address _to, uint256 _value) public returns (bool);
function approve(address _spender, uint256 _value)
public returns (bool);
function transferFrom(address _from, address _to, uint256 _value)
public returns (bool);
event Transfer(
address indexed from,
address indexed to,
uint256 value
);
event Approval(
address indexed owner,
address indexed spender,
uint256 value
);
}
// File: contracts\math\SafeMath.sol
/**
* #title SafeMath
* #dev Math operations with safety checks that revert on error
*/
library SafeMath {
/**
* #dev Multiplies two numbers, reverts on overflow.
*/
function mul(uint256 _a, uint256 _b) internal pure returns (uint256) {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522
if (_a == 0) {
return 0;
}
uint256 c = _a * _b;
require(c / _a == _b);
return c;
}
/**
* #dev Integer division of two numbers truncating the quotient, reverts on division by zero.
*/
function div(uint256 _a, uint256 _b) internal pure returns (uint256) {
require(_b > 0); // Solidity only automatically asserts when dividing by 0
uint256 c = _a / _b;
// assert(_a == _b * c + _a % _b); // There is no case in which this doesn't hold
return c;
}
/**
* #dev Subtracts two numbers, reverts on overflow (i.e. if subtrahend is greater than minuend).
*/
function sub(uint256 _a, uint256 _b) internal pure returns (uint256) {
require(_b <= _a);
uint256 c = _a - _b;
return c;
}
/**
* #dev Adds two numbers, reverts on overflow.
*/
function add(uint256 _a, uint256 _b) internal pure returns (uint256) {
uint256 c = _a + _b;
require(c >= _a);
return c;
}
/**
* #dev Divides two numbers and returns the remainder (unsigned integer modulo),
* reverts when dividing by zero.
*/
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
require(b != 0);
return a % b;
}
}
// File: contracts\token\ERC20\StandardToken.sol
/**
* #title Standard ERC20 token
*
* #dev Implementation of the basic standard token.
* https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md
* Based on code by FirstBlood: https://github.com/Firstbloodio/token/blob/master/smart_contract/FirstBloodToken.sol
*/
contract StandardToken is ERC20 {
using SafeMath for uint256;
mapping (address => uint256) private balances;
mapping (address => mapping (address => uint256)) private allowed;
uint256 public totalSupply_;
/**
* #dev Total number of tokens in existence
*/
function totalSupply() public view returns (uint256) {
return totalSupply_;
}
/**
* #dev Gets the balance of the specified address.
* #param _owner The address to query the the balance of.
* #return An uint256 representing the amount owned by the passed address.
*/
function balanceOf(address _owner) public view returns (uint256) {
return balances[_owner];
}
/**
* #dev Function to check the amount of tokens that an owner allowed to a spender.
* #param _owner address The address which owns the funds.
* #param _spender address The address which will spend the funds.
* #return A uint256 specifying the amount of tokens still available for the spender.
*/
function allowance(
address _owner,
address _spender
)
public
view
returns (uint256)
{
return allowed[_owner][_spender];
}
/**
* #dev Transfer token for a specified address
* #param _to The address to transfer to.
* #param _value The amount to be transferred.
*/
function transfer(address _to, uint256 _value) public returns (bool) {
require(_value <= balances[msg.sender]);
require(_to != address(0));
balances[msg.sender] = balances[msg.sender].sub(_value);
balances[_to] = balances[_to].add(_value);
emit Transfer(msg.sender, _to, _value);
return true;
}
/**
* #dev Approve the passed address to spend the specified amount of tokens on behalf of msg.sender.
* Beware that changing an allowance with this method brings the risk that someone may use both the old
* and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this
* race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
* #param _spender The address which will spend the funds.
* #param _value The amount of tokens to be spent.
*/
function approve(address _spender, uint256 _value) public returns (bool) {
allowed[msg.sender][_spender] = _value;
emit Approval(msg.sender, _spender, _value);
return true;
}
/**
* #dev Transfer tokens from one address to another
* #param _from address The address which you want to send tokens from
* #param _to address The address which you want to transfer to
* #param _value uint256 the amount of tokens to be transferred
*/
function transferFrom(
address _from,
address _to,
uint256 _value
)
public
returns (bool)
{
require(_value <= balances[_from]);
require(_value <= allowed[_from][msg.sender]);
require(_to != address(0));
balances[_from] = balances[_from].sub(_value);
balances[_to] = balances[_to].add(_value);
allowed[_from][msg.sender] = allowed[_from][msg.sender].sub(_value);
emit Transfer(_from, _to, _value);
return true;
}
/**
* #dev Increase the amount of tokens that an owner allowed to a spender.
* approve should be called when allowed[_spender] == 0. To increment
* allowed value is better to use this function to avoid 2 calls (and wait until
* the first transaction is mined)
* From MonolithDAO Token.sol
* #param _spender The address which will spend the funds.
* #param _addedValue The amount of tokens to increase the allowance by.
*/
function increaseApproval(
address _spender,
uint256 _addedValue
)
public
returns (bool)
{
allowed[msg.sender][_spender] = (
allowed[msg.sender][_spender].add(_addedValue));
emit Approval(msg.sender, _spender, allowed[msg.sender][_spender]);
return true;
}
/**
* #dev Decrease the amount of tokens that an owner allowed to a spender.
* approve should be called when allowed[_spender] == 0. To decrement
* allowed value is better to use this function to avoid 2 calls (and wait until
* the first transaction is mined)
* From MonolithDAO Token.sol
* #param _spender The address which will spend the funds.
* #param _subtractedValue The amount of tokens to decrease the allowance by.
*/
function decreaseApproval(
address _spender,
uint256 _subtractedValue
)
public
returns (bool)
{
uint256 oldValue = allowed[msg.sender][_spender];
if (_subtractedValue >= oldValue) {
allowed[msg.sender][_spender] = 0;
} else {
allowed[msg.sender][_spender] = oldValue.sub(_subtractedValue);
}
emit Approval(msg.sender, _spender, allowed[msg.sender][_spender]);
return true;
}
/**
* #dev Internal function that mints an amount of the token and assigns it to
* an account. This encapsulates the modification of balances such that the
* proper events are emitted.
* #param _account The account that will receive the created tokens.
* #param _amount The amount that will be created.
*/
function _mint(address _account, uint256 _amount) internal {
require(_account != 0);
totalSupply_ = totalSupply_.add(_amount);
balances[_account] = balances[_account].add(_amount);
emit Transfer(address(0), _account, _amount);
}
/**
* #dev Internal function that burns an amount of the token of a given
* account.
* #param _account The account whose tokens will be burnt.
* #param _amount The amount that will be burnt.
*/
function _burn(address _account, uint256 _amount) internal {
require(_account != 0);
require(balances[_account] > _amount);
totalSupply_ = totalSupply_.sub(_amount);
balances[_account] = balances[_account].sub(_amount);
emit Transfer(_account, address(0), _amount);
}
/**
* #dev Internal function that burns an amount of the token of a given
* account, deducting from the sender's allowance for said account. Uses the
* internal _burn function.
* #param _account The account whose tokens will be burnt.
* #param _amount The amount that will be burnt.
*/
function _burnFrom(address _account, uint256 _amount) internal {
require(allowed[_account][msg.sender] > _amount);
// Should https://github.com/OpenZeppelin/zeppelin-solidity/issues/707 be accepted,
// this function needs to emit an event with the updated approval.
allowed[_account][msg.sender] = allowed[_account][msg.sender].sub(_amount);
_burn(_account, _amount);
}
}
// File: contracts\token\ERC20\BurnableToken.sol
/**
* #title Burnable Token
* #dev Token that can be irreversibly burned (destroyed).
*/
contract BurnableToken is StandardToken {
event Burn(address indexed burner, uint256 value);
/**
* #dev Burns a specific amount of tokens.
* #param _value The amount of token to be burned.
*/
function burn(uint256 _value) public {
_burn(msg.sender, _value);
}
/**
* #dev Burns a specific amount of tokens from the target address and decrements allowance
* #param _from address The address which you want to send tokens from
* #param _value uint256 The amount of token to be burned
*/
function burnFrom(address _from, uint256 _value) public {
_burnFrom(_from, _value);
}
/**
* #dev Overrides StandardToken._burn in order for burn and burnFrom to emit
* an additional Burn event.
*/
function _burn(address _who, uint256 _value) internal {
super._burn(_who, _value);
emit Burn(_who, _value);
}
}
/**
* #title KWATT_Token Token
* #dev Token that can be irreversibly burned (destroyed).
*/
contract KWATT_Token is BurnableToken {
string public name = "Token";
string public symbol = "TKN";
uint8 public decimals = 18;
uint public INITIAL_SUPPLY = 300000000;
constructor() public {
totalSupply_ = INITIAL_SUPPLY;
balanceOf[msg.sender] = totalSupply_;
}
}
You can use balances instead of balanceOf, but you'll first need to switch that variable's visibility to internal instead of private.
I am trying to send ERC-20 token that was deposited to my contract address to another address. Here is the ERC-20 contract code -
pragma solidity ^0.4.11;
/**
* Math operations with safety checks
*/
library SafeMath {
function mul(uint a, uint b) internal returns (uint) {
uint c = a * b;
assert(a == 0 || c / a == b);
return c;
}
function div(uint a, uint b) internal returns (uint) {
// assert(b > 0); // Solidity automatically throws when dividing by 0
uint c = a / b;
// assert(a == b * c + a % b); // There is no case in which this doesn't hold
return c;
}
function sub(uint a, uint b) internal returns (uint) {
assert(b <= a);
return a - b;
}
function add(uint a, uint b) internal returns (uint) {
uint c = a + b;
assert(c >= a);
return c;
}
function max64(uint64 a, uint64 b) internal constant returns (uint64) {
return a >= b ? a : b;
}
function min64(uint64 a, uint64 b) internal constant returns (uint64) {
return a < b ? a : b;
}
function max256(uint256 a, uint256 b) internal constant returns (uint256) {
return a >= b ? a : b;
}
function min256(uint256 a, uint256 b) internal constant returns (uint256) {
return a < b ? a : b;
}
function assert(bool assertion) internal {
if (!assertion) {
throw;
}
}
}
/**
* #title ERC20Basic
* #dev Simpler version of ERC20 interface
* #dev see https://github.com/ethereum/EIPs/issues/20
*/
contract ERC20Basic {
uint public totalSupply;
function balanceOf(address who) constant returns (uint);
function transfer(address to, uint value);
event Transfer(address indexed from, address indexed to, uint value);
}
/**
* #title Basic token
* #dev Basic version of StandardToken, with no allowances.
*/
contract BasicToken is ERC20Basic {
using SafeMath for uint;
mapping(address => uint) balances;
/**
* #dev Fix for the ERC20 short address attack.
*/
modifier onlyPayloadSize(uint size) {
if(msg.data.length < size + 4) {
throw;
}
_;
}
/**
* #dev transfer token for a specified address
* #param _to The address to transfer to.
* #param _value The amount to be transferred.
*/
function transfer(address _to, uint _value) onlyPayloadSize(2 * 32) {
balances[msg.sender] = balances[msg.sender].sub(_value);
balances[_to] = balances[_to].add(_value);
Transfer(msg.sender, _to, _value);
}
/**
* #dev Gets the balance of the specified address.
* #param _owner The address to query the the balance of.
* #return An uint representing the amount owned by the passed address.
*/
function balanceOf(address _owner) constant returns (uint balance) {
return balances[_owner];
}
}
/**
* #title ERC20 interface
* #dev see https://github.com/ethereum/EIPs/issues/20
*/
contract ERC20 is ERC20Basic {
function allowance(address owner, address spender) constant returns (uint);
function transferFrom(address from, address to, uint value);
function approve(address spender, uint value);
event Approval(address indexed owner, address indexed spender, uint value);
}
/**
* #title Standard ERC20 token
*
* #dev Implementation of the basic standard token.
* #dev https://github.com/ethereum/EIPs/issues/20
* #dev Based on code by FirstBlood: https://github.com/Firstbloodio/token/blob/master/smart_contract/FirstBloodToken.sol
*/
contract StandardToken is BasicToken, ERC20 {
mapping (address => mapping (address => uint)) allowed;
/**
* #dev Transfer tokens from one address to another
* #param _from address The address which you want to send tokens from
* #param _to address The address which you want to transfer to
* #param _value uint the amout of tokens to be transfered
*/
function transferFrom(address _from, address _to, uint _value) onlyPayloadSize(3 * 32) {
var _allowance = allowed[_from][msg.sender];
// Check is not needed because sub(_allowance, _value) will already throw if this condition is not met
// if (_value > _allowance) throw;
balances[_to] = balances[_to].add(_value);
balances[_from] = balances[_from].sub(_value);
allowed[_from][msg.sender] = _allowance.sub(_value);
Transfer(_from, _to, _value);
}
/**
* #dev Aprove the passed address to spend the specified amount of tokens on beahlf of msg.sender.
* #param _spender The address which will spend the funds.
* #param _value The amount of tokens to be spent.
*/
function approve(address _spender, uint _value) {
// 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 ((_value != 0) && (allowed[msg.sender][_spender] != 0)) throw;
allowed[msg.sender][_spender] = _value;
Approval(msg.sender, _spender, _value);
}
/**
* #dev Function to check the amount of tokens than an owner allowed to a spender.
* #param _owner address The address which owns the funds.
* #param _spender address The address which will spend the funds.
* #return A uint specifing the amount of tokens still avaible for the spender.
*/
function allowance(address _owner, address _spender) constant returns (uint remaining) {
return allowed[_owner][_spender];
}
}
/**
* #title Ownable
* #dev The Ownable contract has an owner address, and provides basic authorization control
* functions, this simplifies the implementation of "user permissions".
*/
contract Ownable {
address public owner;
/**
* #dev The Ownable constructor sets the original `owner` of the contract to the sender
* account.
*/
function Ownable() {
owner = msg.sender;
}
/**
* #dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
if (msg.sender != owner) {
throw;
}
_;
}
/**
* #dev Allows the current owner to transfer control of the contract to a newOwner.
* #param newOwner The address to transfer ownership to.
*/
function transferOwnership(address newOwner) onlyOwner {
if (newOwner != address(0)) {
owner = newOwner;
}
}
}
/**
* #title Mintable token
* #dev Simple ERC20 Token example, with mintable token creation
* #dev Issue: * https://github.com/OpenZeppelin/zeppelin-solidity/issues/120
* Based on code by TokenMarketNet: https://github.com/TokenMarketNet/ico/blob/master/contracts/MintableToken.sol
*/
contract MintableToken is StandardToken, Ownable {
event Mint(address indexed to, uint value);
event MintFinished();
bool public mintingFinished = false;
uint public totalSupply = 0;
modifier canMint() {
if(mintingFinished) throw;
_;
}
/**
* #dev Function to mint tokens
* #param _to The address that will recieve the minted tokens.
* #param _amount The amount of tokens to mint.
* #return A boolean that indicates if the operation was successful.
*/
function mint(address _to, uint _amount) onlyOwner canMint returns (bool) {
totalSupply = totalSupply.add(_amount);
balances[_to] = balances[_to].add(_amount);
Mint(_to, _amount);
return true;
}
/**
* #dev Function to stop minting new tokens.
* #return True if the operation was successful.
*/
function finishMinting() onlyOwner returns (bool) {
mintingFinished = true;
MintFinished();
return true;
}
}
/**
* #title Pausable
* #dev Base contract which allows children to implement an emergency stop mechanism.
*/
contract Pausable is Ownable {
event Pause();
event Unpause();
bool public paused = false;
/**
* #dev modifier to allow actions only when the contract IS paused
*/
modifier whenNotPaused() {
if (paused) throw;
_;
}
/**
* #dev modifier to allow actions only when the contract IS NOT paused
*/
modifier whenPaused {
if (!paused) throw;
_;
}
/**
* #dev called by the owner to pause, triggers stopped state
*/
function pause() onlyOwner whenNotPaused returns (bool) {
paused = true;
Pause();
return true;
}
/**
* #dev called by the owner to unpause, returns to normal state
*/
function unpause() onlyOwner whenPaused returns (bool) {
paused = false;
Unpause();
return true;
}
}
/**
* Pausable token
*
* Simple ERC20 Token example, with pausable token creation
**/
contract PausableToken is StandardToken, Pausable {
function transfer(address _to, uint _value) whenNotPaused {
super.transfer(_to, _value);
}
function transferFrom(address _from, address _to, uint _value) whenNotPaused {
super.transferFrom(_from, _to, _value);
}
}
/**
* #title TokenTimelock
* #dev TokenTimelock is a token holder contract that will allow a
* beneficiary to extract the tokens after a time has passed
*/
contract TokenTimelock {
// ERC20 basic token contract being held
ERC20Basic token;
// beneficiary of tokens after they are released
address beneficiary;
// timestamp where token release is enabled
uint releaseTime;
function TokenTimelock(ERC20Basic _token, address _beneficiary, uint _releaseTime) {
require(_releaseTime > now);
token = _token;
beneficiary = _beneficiary;
releaseTime = _releaseTime;
}
/**
* #dev beneficiary claims tokens held by time lock
*/
function claim() {
require(msg.sender == beneficiary);
require(now >= releaseTime);
uint amount = token.balanceOf(this);
require(amount > 0);
token.transfer(beneficiary, amount);
}
}
contract TestToken is PausableToken, MintableToken {
using SafeMath for uint256;
string public name = "TestToken";
string public symbol = "TT";
uint public decimals = 18;
/**
* #dev mint timelocked tokens
*/
function mintTimelocked(address _to, uint256 _amount, uint256 _releaseTime)
onlyOwner canMint returns (TokenTimelock) {
TokenTimelock timelock = new TokenTimelock(this, _to, _releaseTime);
mint(timelock, _amount);
return timelock;
}
}
And the following is the contract from which I'm trying to send the deposited tokens -
pragma solidity ^0.4.18;
contract ERC20Interface {
// Send _value amount of tokens to address _to
function transfer(address _to, uint256 _value) public returns (bool success);
// Get the account balance of another account with address _owner
function balanceOf(address _owner) public constant returns (uint256 balance);
}
/**
* Contract that will forward any incoming Ether to the creator of the contract
*/
contract Forwarder {
// Address to which any funds sent to this contract will be forwarded
address public parentAddress;
event ForwarderDeposited(address from, uint value, bytes data);
/**
* Create the contract, and sets the destination address to that of the creator
*/
function Forwarder() public {
parentAddress = msg.sender;
}
/**
* Modifier that will execute internal code block only if the sender is the parent address
*/
modifier onlyParent {
if (msg.sender != parentAddress) {
revert();
}
_;
}
/**
* Default function; Gets called when Ether is deposited, and forwards it to the parent address
*/
function() public payable {
// throws on failure
parentAddress.transfer(msg.value);
// Fire off the deposited event if we can forward it
ForwarderDeposited(msg.sender, msg.value, msg.data);
}
/**
* Execute a token transfer of the full balance from the forwarder token to the parent address
* #param tokenContractAddress the address of the erc20 token contract
*/
function flushTokens(address tokenContractAddress) public onlyParent {
ERC20Interface instance = ERC20Interface(tokenContractAddress);
var forwarderAddress = address(this);
var forwarderBalance = instance.balanceOf(forwarderAddress);
if (forwarderBalance == 0) {
return;
}
if (!instance.transfer(parentAddress, forwarderBalance)) {
revert();
}
}
}
When I call the flushToken function I get an error - Error: gas required exceeds allowance or always failing transaction.
In order to transfer tokens from one address to another you need first to approve the transaction.
function approve(address spender, uint tokens) public returns (bool success);
In that was you approve that the second contract can transfer the money from the first contract.
You can check the allowance wit this function
function allowance(address tokenOwner, address spender) public constant returns (uint remaining);