diff --git a/src/transaction-allocator/modules/transaction-allocation/interfaces/ITATransactionAllocation.sol b/src/transaction-allocator/modules/transaction-allocation/interfaces/ITATransactionAllocation.sol index f56a956..7b75728 100644 --- a/src/transaction-allocator/modules/transaction-allocation/interfaces/ITATransactionAllocation.sol +++ b/src/transaction-allocator/modules/transaction-allocation/interfaces/ITATransactionAllocation.sol @@ -50,5 +50,5 @@ interface ITATransactionAllocation is ITATransactionAllocationEventsErrors, ITAT uint256 _totalStake, uint256 _totalTransactions, FixedPointType _zScore - ) external view returns (FixedPointType); + ) external pure returns (FixedPointType); } diff --git a/test/core/RelayerLivenessAndJailing.t.sol b/test/core/RelayerLivenessAndJailing.t.sol index 0aa2ee2..f3ac42b 100644 --- a/test/core/RelayerLivenessAndJailing.t.sol +++ b/test/core/RelayerLivenessAndJailing.t.sol @@ -21,6 +21,7 @@ contract RelayerLivenessAndJailingTest is uint256 constant initialApplicationFunds = 10 ether; mapping(RelayerAddress => uint256) penalty; + VerifyRelayerLivenessDifferentialHelper v = new VerifyRelayerLivenessDifferentialHelper(); function setUp() public override { if (tx.gasprice == 0) { @@ -535,4 +536,63 @@ contract RelayerLivenessAndJailingTest is ta.unjailAndReenter(latestRelayerState, initialRelayerStake[inactiveRelayer]); vm.stopPrank(); } + + /// forge-config: test.fuzz.runs = 2048 + function testDifferentialOptimisedVerifyRelayerLivenessAgainstReferenceImplementation( + uint256 _relayerStake, + uint256 _totalStake, + uint256 _transactionsDoneByRelayer, + uint256 _totalTransactions + ) external { + vm.assume(_relayerStake > 0); + vm.assume(_totalStake > 0); + vm.assume(_transactionsDoneByRelayer > 0); + vm.assume(_totalTransactions > 0); + vm.assume(_relayerStake <= _totalStake); + vm.assume(_transactionsDoneByRelayer <= _totalTransactions); + vm.assume(_totalStake <= 1_000_000_000 ether); + vm.assume(_totalTransactions <= 1_000_000_000); + + assertEq( + v.verifyRelayerLivenessReferenceImplementation( + _relayerStake, _totalStake, _transactionsDoneByRelayer, _totalTransactions, ta.livenessZParameter() + ), + v.verifyRelayerLivenessOptimisedImplementation( + _relayerStake, _totalStake, _transactionsDoneByRelayer, _totalTransactions, ta.livenessZParameter() + ) + ); + } +} + +contract VerifyRelayerLivenessDifferentialHelper is TATransactionAllocation { + TATransactionAllocation t; + + using Uint256WrapperHelper for uint256; + + constructor() { + t = new TATransactionAllocation(); + } + + function verifyRelayerLivenessReferenceImplementation( + uint256 _relayerStake, + uint256 _totalStake, + uint256 _transactionsDoneByRelayer, + uint256 _totalTransactions, + FixedPointType _zScore + ) external view returns (bool) { + return _transactionsDoneByRelayer.fp() + >= t.calculateMinimumTranasctionsForLiveness(_relayerStake, _totalStake, _totalTransactions, _zScore); + } + + function verifyRelayerLivenessOptimisedImplementation( + uint256 _relayerStake, + uint256 _totalStake, + uint256 _transactionsDoneByRelayer, + uint256 _totalTransactions, + FixedPointType _zScore + ) external pure returns (bool) { + return _checkRelayerLiveness( + _relayerStake, _totalStake, _transactionsDoneByRelayer, _totalTransactions, _zScore * _zScore + ); + } }