Set a fixed fee transferred to the caller for publication

Avoids the risk of the gas used by the contract exceeding the gas presumed to
be used (causing an insolvency).
This commit is contained in:
Luke Parker
2024-09-20 00:20:05 -04:00
parent ec9211fd84
commit bc1bbf9951
5 changed files with 28 additions and 54 deletions

View File

@@ -164,18 +164,16 @@ contract Router {
// Execute a list of transactions if they were signed by the current key with the current nonce
function execute(
address coin,
uint256 fee_per_gas,
uint256 fee,
OutInstruction[] calldata transactions,
Signature calldata signature
) external {
uint256 gasLeftAtStart = gasleft();
// Verify the signature
// We hash the message here as we need the message's hash for the Executed event
// Since we're already going to hash it, hashing it prior to verifying the signature reduces the
// amount of words hashed by its challenge function (reducing our gas costs)
bytes32 message =
keccak256(abi.encode("execute", block.chainid, _nonce, coin, fee_per_gas, transactions));
keccak256(abi.encode("execute", block.chainid, _nonce, coin, fee, transactions));
if (!Schnorr.verify(_seraiKey, message, signature.c, signature.s)) {
revert InvalidSignature();
}
@@ -212,25 +210,8 @@ contract Router {
}
}
// Calculate the gas which will be used to transfer the fee out
// This is meant to be always over, never under, with any excess being a tip to the publisher
uint256 gasToTransferOut;
if (coin == address(0)) {
// 5,000 gas is explicitly allowed, with another 10,000 for whatever overhead remains
// unaccounted for
gasToTransferOut = 15_000;
} else {
// 100_000 gas is explicitly allowed, with another 15,000 for whatever overhead remains
// unaccounted for. More gas is given than for ETH due to needing to ABI encode the function
// call
gasToTransferOut = 115_000;
}
// Calculate the gas used
uint256 gasLeftAtEnd = gasleft();
uint256 gasUsed = gasLeftAtStart - gasLeftAtEnd;
// Transfer to the caller the fee
_transferOut(msg.sender, coin, (gasUsed + gasToTransferOut) * fee_per_gas);
_transferOut(msg.sender, coin, fee);
}
function nonce() external view returns (uint256) {

View File

@@ -325,27 +325,18 @@ impl Router {
chain_id: U256,
nonce: u64,
coin: Coin,
fee_per_gas: U256,
fee: U256,
outs: OutInstructions,
) -> Vec<u8> {
("execute", chain_id, U256::try_from(nonce).unwrap(), coin.address(), fee_per_gas, outs.0)
.abi_encode()
("execute", chain_id, U256::try_from(nonce).unwrap(), coin.address(), fee, outs.0).abi_encode()
}
/// Construct a transaction to execute a batch of `OutInstruction`s.
pub fn execute(
&self,
coin: Coin,
fee_per_gas: U256,
outs: OutInstructions,
sig: &Signature,
) -> TxLegacy {
pub fn execute(&self, coin: Coin, fee: U256, outs: OutInstructions, sig: &Signature) -> TxLegacy {
let outs_len = outs.0.len();
TxLegacy {
to: TxKind::Call(self.1),
input: abi::executeCall::new((coin.address(), fee_per_gas, outs.0, sig.into()))
.abi_encode()
.into(),
input: abi::executeCall::new((coin.address(), fee, outs.0, sig.into())).abi_encode().into(),
// TODO
gas_limit: 100_000 + ((200_000 + 10_000) * u128::try_from(outs_len).unwrap()),
..Default::default()