tokenbridge-contracts/contracts/upgradeable_contracts/GSNForeignERC20Bridge.sol

70 lines
2.8 KiB
Solidity

pragma solidity 0.4.24;
import "./BasicForeignBridge.sol";
import "./ERC20Bridge.sol";
import "../gsn/BaseRelayRecipient.sol";
import "../gsn/interfaces/IKnowForwarderAddress.sol";
contract GSNForeignERC20Bridge is BasicForeignBridge, ERC20Bridge, BaseRelayRecipient, IKnowForwarderAddress {
bytes32 internal constant PAYMASTER = 0xfefcc139ed357999ed60c6a013947328d52e7d9751e93fd0274a2bfae5cbcb12; // keccak256(abi.encodePacked("paymaster"))
bytes32 internal constant TRUSTED_FORWARDER = 0x222cb212229f0f9bcd249029717af6845ea3d3a84f22b54e5744ac25ef224c92; // keccak256(abi.encodePacked("trustedForwarder"))
function versionRecipient() external view returns (string memory) {
return "1.0.1";
}
function getTrustedForwarder() external view returns (address) {
return addressStorage[TRUSTED_FORWARDER];
}
function setTrustedForwarder(address _trustedForwarder) public onlyOwner {
addressStorage[TRUSTED_FORWARDER] = _trustedForwarder;
}
function isTrustedForwarder(address forwarder) public view returns (bool) {
return forwarder == addressStorage[TRUSTED_FORWARDER];
}
function setPayMaster(address _paymaster) public onlyOwner {
addressStorage[PAYMASTER] = _paymaster;
}
/**
* @param message same as in `executeSignatures`
* @param signatures same as in `executeSignatures`
* @param maxTokensFee maximum amount of foreign tokens that user allows to take
* as a commission
*/
function executeSignaturesGSN(bytes message, bytes signatures, uint256 maxTokensFee) external {
// Allow only forwarder calls
require(isTrustedForwarder(msg.sender), "invalid forwarder");
Message.hasEnoughValidSignatures(message, signatures, validatorContract(), false);
address recipient;
uint256 amount;
bytes32 txHash;
address contractAddress;
(recipient, amount, txHash, contractAddress) = Message.parseMessage(message);
if (withinExecutionLimit(amount)) {
require(maxTokensFee <= amount);
require(contractAddress == address(this));
require(!relayedMessages(txHash));
setRelayedMessages(txHash, true);
require(onExecuteMessageGSN(recipient, amount, maxTokensFee));
emit RelayedMessage(recipient, amount, txHash);
} else {
onFailedMessage(recipient, amount, txHash);
}
}
function onExecuteMessageGSN(address recipient, uint256 amount, uint256 fee) internal returns (bool) {
addTotalExecutedPerDay(getCurrentDay(), amount);
// Send maxTokensFee to paymaster
ERC20 token = erc20token();
bool first = token.transfer(addressStorage[PAYMASTER], fee);
bool second = token.transfer(recipient, amount - fee);
return first && second;
}
}