Skip to content

Commit

Permalink
Differential Testing with --ffi flag (#60)
Browse files Browse the repository at this point in the history
* Differential testing

* testing framework

* Workflow fixed to install python

* Cleanup

* Added eth-abi installation

* formatting
  • Loading branch information
Keshavrajsinghal authored Jun 26, 2024
1 parent fbad20c commit d340c79
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 1 deletion.
12 changes: 11 additions & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,16 @@ jobs:
with:
submodules: recursive

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.8'

- name: Install eth-abi
run: |
python3 -m pip install --upgrade pip
python3 -m pip install eth-abi
- name: Install Foundry
uses: foundry-rs/foundry-toolchain@v1
with:
Expand All @@ -30,7 +40,7 @@ jobs:

- name: Run Forge tests
run: |
forge test -vvv
forge test -vvv --ffi
id: test

- name: Check formatting
Expand Down
32 changes: 32 additions & 0 deletions py/compute_premium.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import sys
from eth_abi import encode

PRECISION = 10 ** 18
SECONDS_PER_DAY = 86400
PER_PERIOD_DECAY_PERCENT = 50
PER_PERIOD_DECAY_PERCENT_WAD = int(PER_PERIOD_DECAY_PERCENT * PRECISION / 100)

class DecayedPriceCalculator:
@staticmethod
def decayed_premium(start_premium, elapsed_seconds):
ratio = elapsed_seconds / SECONDS_PER_DAY
percent_wad_remaining_per_period = (PRECISION - PER_PERIOD_DECAY_PERCENT_WAD) / PRECISION
multiplier = (percent_wad_remaining_per_period ** ratio)
price = (start_premium * multiplier)
return int(price)

@classmethod
def calculate_from_cli(cls):
if len(sys.argv) != 3:
print("Usage: python3 price.py <start_premium> <elapsed_seconds>")
sys.exit(1)

start_premium = int(sys.argv[1])
elapsed_seconds = int(sys.argv[2])

result = cls.decayed_premium(start_premium, elapsed_seconds)
enc = encode(['uint256'], [result])
print("0x" + enc.hex())

if __name__ == "__main__":
DecayedPriceCalculator.calculate_from_cli()
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,21 @@ contract ExponentialPremiumFuzzTest is ExponentialPremiumOracleBase {

assert(premium1 >= premium2);
}

function test_decayedPremium_accuracy(uint256 elapsed) public {
uint256 bound = 400 * 1 days;
vm.assume(elapsed <= bound);
string[] memory input = new string[](4);
input[0] = "python3";
input[1] = "py/compute_premium.py";
input[2] = vm.toString(startPremium);
input[3] = vm.toString(elapsed);
uint256 result = oracle.decayedPremium(elapsed);
bytes memory res = vm.ffi(input);
uint256 expected = abi.decode(res, (uint256));
uint256 leftBound = (expected * (999)) / 1000;
uint256 rightBound = (expected * (1001)) / 1000;
bool withinBounds = (leftBound <= result && result <= rightBound); // Checking accuracy within 0.1 percent of the expected result
assertTrue(withinBounds);
}
}

0 comments on commit d340c79

Please sign in to comment.