maticnetwork / pos-portal

Smart contracts that powers the PoS (proof-of-stake) based bridge mechanism for Matic Network
GNU General Public License v3.0
356 stars 254 forks source link

Want to change the address of my mapped token and redeploy with the following contract #91

Closed ednawnika closed 3 years ago

ednawnika commented 3 years ago

Token: AFTR Token type ERC20 Ethereum address 0x56dfa98f363edb99240b63f8a5141d8b64cfaf6e Polygon address 0x228a22bf6da9353Abbe37a31cf85c02dfC432456 Decimals 8 Mintable false

ednawnika commented 3 years ago

Im attaching the required contracts

ednawnika commented 3 years ago

// File: openzeppelin-solidity/contracts/GSN/Context.sol

pragma solidity ^0.5.0;

/*

// File: openzeppelin-solidity/contracts/token/ERC20/IERC20.sol

pragma solidity ^0.5.0;

/**

// File: openzeppelin-solidity/contracts/math/SafeMath.sol

pragma solidity ^0.5.0;

/**

// File: openzeppelin-solidity/contracts/token/ERC20/ERC20.sol

pragma solidity ^0.5.0;

/**

// File: openzeppelin-solidity/contracts/access/Roles.sol

pragma solidity ^0.5.0;

/**

// File: openzeppelin-solidity/contracts/access/roles/MinterRole.sol

pragma solidity ^0.5.0;

contract MinterRole is Context { using Roles for Roles.Role;

event MinterAdded(address indexed account);
event MinterRemoved(address indexed account);

Roles.Role private _minters;

constructor () internal {
    _addMinter(_msgSender());
}

modifier onlyMinter() {
    require(isMinter(_msgSender()), "MinterRole: caller does not have the Minter role");
    _;
}

function isMinter(address account) public view returns (bool) {
    return _minters.has(account);
}

function addMinter(address account) public onlyMinter {
    _addMinter(account);
}

function renounceMinter() public {
    _removeMinter(_msgSender());
}

function _addMinter(address account) internal {
    _minters.add(account);
    emit MinterAdded(account);
}

function _removeMinter(address account) internal {
    _minters.remove(account);
    emit MinterRemoved(account);
}

}

// File: original_contracts/EIP712Base.sol

pragma solidity 0.5.17;

contract EIP712Base {

struct EIP712Domain {
    string name;
    string version;
    uint256 chainId;
    address verifyingContract;
}

bytes32 internal constant EIP712_DOMAIN_TYPEHASH = keccak256(bytes("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"));

bytes32 internal domainSeperator;

uint256 private _chainid;

constructor(string memory name, string memory version, uint256 chainid) public {
  _chainid = chainid;

  domainSeperator = keccak256(abi.encode(
        EIP712_DOMAIN_TYPEHASH,
        keccak256(bytes(name)),
        keccak256(bytes(version)),
        getChainID(),
        address(this)
    ));
}

function getChainID() public view returns (uint256 id) {
        return _chainid;
}

function getDomainSeperator() private view returns(bytes32) {
    return domainSeperator;
}

/**
* Accept message hash and returns hash message in EIP712 compatible form
* So that it can be used to recover signer from signature signed using EIP712 formatted data
* https://eips.ethereum.org/EIPS/eip-712
* "\\x19" makes the encoding deterministic
* "\\x01" is the version byte to make it compatible to EIP-191
*/
function toTypedMessageHash(bytes32 messageHash) internal view returns(bytes32) {
    return keccak256(abi.encodePacked("\x19\x01", getDomainSeperator(), messageHash));
}

}

// File: original_contracts/EIP712MetaTransaction.sol

pragma solidity 0.5.17;

contract EIP712MetaTransaction is EIP712Base { using SafeMath for uint256; bytes32 private constant META_TRANSACTION_TYPEHASH = keccak256( bytes( "MetaTransaction(uint256 nonce,address from,bytes functionSignature)" ) );

event MetaTransactionExecuted(
    address userAddress,
    address payable relayerAddress,
    bytes functionSignature
);
mapping(address => uint256) nonces;

/*
 * Meta transaction structure.
 * No point of including value field here as if user is doing value transfer then he has the funds to pay for gas
 * He should call the desired function directly in that case.
 */
struct MetaTransaction {
    uint256 nonce;
    address from;
    bytes functionSignature;
}

constructor(string memory name, string memory version, uint256 chainid)
    public
    EIP712Base(name, version, chainid)
{}

function executeMetaTransaction(
    address userAddress,
    bytes memory functionSignature,
    bytes32 sigR,
    bytes32 sigS,
    uint8 sigV
) public payable returns (bytes memory) {
    MetaTransaction memory metaTx = MetaTransaction({
        nonce: nonces[userAddress],
        from: userAddress,
        functionSignature: functionSignature
    });
    require(
        verify(userAddress, metaTx, sigR, sigS, sigV),
        "Signer and signature do not match"
    );
    // Append userAddress and relayer address at the end to extract it from calling context
    (bool success, bytes memory returnData) = address(this).call(
        abi.encodePacked(functionSignature, userAddress)
    );

    require(success, "Function call not successfull");
    nonces[userAddress] = nonces[userAddress].add(1);
    emit MetaTransactionExecuted(
        userAddress,
        msg.sender,
        functionSignature
    );
    return returnData;
}

function hashMetaTransaction(MetaTransaction memory metaTx)
    internal
    view
    returns (bytes32)
{
    return
        keccak256(
            abi.encode(
                META_TRANSACTION_TYPEHASH,
                metaTx.nonce,
                metaTx.from,
                keccak256(metaTx.functionSignature)
            )
        );
}

function getNonce(address user) public view returns (uint256 nonce) {
    nonce = nonces[user];
}

function verify(
    address signer,
    MetaTransaction memory metaTx,
    bytes32 sigR,
    bytes32 sigS,
    uint8 sigV
) internal view returns (bool) {
    return
        signer ==
        ecrecover(
            toTypedMessageHash(hashMetaTransaction(metaTx)),
            sigV,
            sigR,
            sigS
        );
}

function _msgSender() internal view returns (address payable sender) {
    if(msg.sender == address(this)) {
        bytes memory array = msg.data;
        uint256 index = msg.data.length;
        assembly {
            // Load the 32 bytes word from memory with the address on the lower 20 bytes, and mask those.
            sender := and(mload(add(array, index)), 0xffffffffffffffffffffffffffffffffffffffff)
        }
    } else {
        sender = msg.sender;
    }
    return sender;
}

}

// File: original_contracts/interfaces/IFeeSettings.sol

pragma solidity 0.5.17;

interface IFeeSettings {

function getFeeWallet() external view returns(address);

function getFeePercentage() external view returns(uint256);

function getMinimumFee() external view returns(uint256);

function changeFeeWallet(address feeWallet) external;

function changeFeePercentage(uint256 feePercentage) external;

function changeMinimuFee(uint256 minimumFee) external;

}

// File: original_contracts/Token.sol

pragma solidity 0.5.17;

contract Token is ERC20, MinterRole, EIP712MetaTransaction {

string public name;
string public symbol;
uint8 public decimals;

mapping(address=>uint256) public userLastActivityBlock;

//Number of blocks after which points will be expired for the user, if no activity is done within that time period
uint256 public expiryThreshold;

IFeeSettings public feeSettings;

event MintWithId(
    address indexed minter,
    address indexed account,
    uint256 amount,
    string id
);

event BurnWithId(
    address indexed burner,
    uint256 amount,
    string id
);

event ExpiryThresholdChanged(
    uint256 newTHreshold
);

event FeeTaken(address indexed receiver, uint256 amount);

constructor(
    string memory _name,
    string memory _symbol,
    uint8 _decimals,
    address _feeSettings,
    uint256 chainid
)
    public
    EIP712MetaTransaction("Afrofuture", "0.1", chainid)
{
    name = _name;
    symbol = _symbol;
    decimals = _decimals;
    feeSettings = IFeeSettings(_feeSettings);
}

function changeExpiryThreshold(uint256 threshold) external onlyMinter {
    expiryThreshold = threshold;
    emit ExpiryThresholdChanged(threshold);
}

function mintWithId(
    address account,
    uint256 amount,
    string calldata id
)
    external
    onlyMinter
    returns (bool)
{
    checkAndBurnExpiredTokens(account);

    userLastActivityBlock[account] = block.number;

    _mint(account, amount);
    _takeFee(amount);
    emit MintWithId(
        _msgSender(),
        account,
        amount,
        id
    );
    return true;
}

function burnWithId(
    uint256 amount,
    string calldata id
)
    external
{
    bool expired = checkAndBurnExpiredTokens(_msgSender());

    if(expired) {
        return;
    }

    userLastActivityBlock[_msgSender()] = block.number;
    _burn(_msgSender(), amount);

    emit BurnWithId(
        _msgSender(),
        amount,
        id
    );
}

function checkAndBurnExpiredTokens(address user) public returns(bool) {
    if (isExpired(user)) {
        _burn(user, balanceOf(user));

        emit BurnWithId(
            user,
            balanceOf(user),
            "EXPIRED"
        );
        return true;
    }
    else {
        return false;
    }
}

function isExpired(address user) public returns(bool) {
    if ( expiryThreshold > 0 && balanceOf(user) > 0 && userLastActivityBlock[user].add(expiryThreshold) < block.number) {
        return true;
    }
    else {
        return false;
    }
}

function _transfer(
    address sender,
    address recipient,
    uint256 amount
)
    internal
{
    checkAndBurnExpiredTokens(sender);
    checkAndBurnExpiredTokens(recipient);
    userLastActivityBlock[sender] = block.number;
    userLastActivityBlock[recipient] = block.number;

    super._transfer(sender, recipient, amount);
}

function _takeFee(uint256 amount) private {
    if(amount == 0){
        return;
    }

    uint256 fee = amount.mul(feeSettings.getFeePercentage()).div(10000);
    if (fee < feeSettings.getMinimumFee()) {
        fee = feeSettings.getMinimumFee();
    }

    if(fee > 0) {
        _mint(feeSettings.getFeeWallet(), fee);
        emit FeeTaken(feeSettings.getFeeWallet(), fee);
    }

}

}