# How to compute paramHashExpected from SwapCreated event data
# Uses eth_abi.encode() and keccak256
from eth_abi import encode
from web3 import Web3
def compute_swap_hash(e):
# Nested structs must be expanded into tuples
oracle_tuple = (
e.oracleParams.settlerReward,
e.oracleParams.initialLiquidity,
e.oracleParams.escalationHalt,
e.oracleParams.settlementTime,
e.oracleParams.latencyBailout,
e.oracleParams.maxGameTime,
e.oracleParams.blocksPerSecond,
e.oracleParams.disputeDelay,
e.oracleParams.swapFee,
e.oracleParams.protocolFee,
e.oracleParams.multiplier,
e.oracleParams.timeType
)
slippage_tuple = (e.priceTolerated, e.toleranceRange)
fulfill_tuple = (
e.fulfillFeeParams.startFulfillFeeIncrease,
e.fulfillFeeParams.maxFee,
e.fulfillFeeParams.startingFee,
e.fulfillFeeParams.roundLength,
e.fulfillFeeParams.growthRate,
e.fulfillFeeParams.maxRounds
)
bounty_tuple = (
e.bountyParams.totalAmtDeposited,
e.bountyParams.bountyStartAmt,
e.bountyParams.roundLength,
e.bountyParams.bountyToken,
e.bountyParams.bountyMultiplier,
e.bountyParams.maxRounds
)
swap_tuple = (
e.sellAmt, e.minOut, e.minFulfillLiquidity, e.expiration,
0, # reportId (always 0 for new swap)
e.gasCompensation,
0, # start (always 0)
0, # fulfillmentFee (always 0)
e.sellToken, e.buyToken, e.swapper,
ADDRESS_ZERO, # matcher
ADDRESS_ZERO, # feeRecipient
True, False, False, False, # active, matched, finished, cancelled
oracle_tuple, slippage_tuple, fulfill_tuple, bounty_tuple
)
SWAP_TYPE = "(uint256,uint256,uint256,uint256,uint256,uint256,uint48,uint24,address,address,address,address,address,bool,bool,bool,bool,(uint256,uint256,uint256,uint48,uint48,uint48,uint32,uint24,uint24,uint24,uint16,bool),(uint256,uint24),(uint48,uint24,uint24,uint24,uint16,uint16),(uint256,uint256,uint256,address,uint16,uint16))"
return keccak256(encode([SWAP_TYPE], [swap_tuple]))