becrypto/contracts/logic/ExecuteRelay.sol
CounterFire2023 d83e480ec3 change sth
2023-10-25 16:10:47 +08:00

97 lines
2.3 KiB
Solidity

// SPDX-License-Identifier: MIT
pragma solidity 0.8.10;
import "../core/HasSignature712.sol";
import "../utils/TimeChecker.sol";
interface IToken {
function transferFrom(
address from,
address to,
uint256 amount
) external returns (bool);
function signApprove(
address spender,
uint256 amount,
uint256 startTime,
uint256 saltNonce,
bytes calldata signature
) external;
}
contract ExecuteRelay is HasSignature712, TimeChecker {
constructor() HasSignature712("ExecuteRelay", "1") {}
address public tokenAddress;
event MethodExecuted(
address indexed sender,
address indexed target,
bytes data,
uint256 gasUsed,
uint256 tokenAmount
);
function execute(
address sender,
address target,
uint256 value,
bytes calldata data,
uint256 startTime,
uint256 saltNonce,
bytes calldata signature
) external payable signatureValid(signature) timeValid(startTime) {
bytes32 messageHash = getMessageHash(
target,
value,
data,
startTime,
saltNonce
);
uint256 gasStart = gasleft();
checkSigner712(sender, messageHash, signature);
uint256 gasPrice = tx.gasprice;
_call(target, value, data);
uint256 gasUsed = gasStart - gasleft();
uint256 tokenAmount = gasPrice * gasUsed; // TODO:: calc real token amount
IToken(tokenAddress).signApprove(
sender,
tokenAmount,
startTime,
saltNonce,
signature
);
IToken(tokenAddress).transferFrom(sender, address(this), tokenAmount);
_useSignature(signature);
emit MethodExecuted(sender, target, data, gasUsed, tokenAmount);
}
/**
* @dev Execute an operation's call.
*
* Emits a {CallExecuted} event.
*/
function _call(address target, uint256 value, bytes calldata data) private {
(bool success, ) = target.call{value: value}(data);
require(success, "ExecuteRelay: underlying transaction reverted");
}
function getMessageHash(
address _target,
uint256 _value,
bytes calldata _data,
uint256 _startTime,
uint256 _saltNonce
) public pure returns (bytes32) {
bytes memory encoded = abi.encodePacked(
_target,
_value,
_data,
_startTime,
_saltNonce
);
return keccak256(encoded);
}
}