70 lines
2.8 KiB
Solidity
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;
|
|
}
|
|
}
|