diff --git a/crates/integration/contracts/Fibonacci.sol b/crates/integration/contracts/Fibonacci.sol new file mode 100644 index 0000000..990c68d --- /dev/null +++ b/crates/integration/contracts/Fibonacci.sol @@ -0,0 +1,62 @@ +// Source: +// https://medium.com/coinmonks/fibonacci-in-solidity-8477d907e22a + +contract FibonacciRecursive { + function f(uint n) internal pure returns (uint) { + if (n <= 1) { + return n; + } else { + return f(n - 1) + f(n - 2); + } + } + + function fib3(uint n) public pure returns (uint) { + return f(n); + } +} + +contract FibonacciIterative { + function fib3(uint n) external pure returns (uint b) { + if (n == 0) { + return 0; + } + uint a = 1; + b = 1; + for (uint i = 2; i < n; i++) { + uint c = a + b; + a = b; + b = c; + } + return b; + } +} + +contract FibonacciBinet { + function fib3(uint n) external pure returns (uint a) { + if (n == 0) { + return 0; + } + uint h = n / 2; + uint mask = 1; + // find highest set bit in n + while (mask <= h) { + mask <<= 1; + } + mask >>= 1; + a = 1; + uint b = 1; + uint c; + while (mask > 0) { + c = a * a + b * b; + if (n & mask > 0) { + b = b * (b + 2 * a); + a = c; + } else { + a = a * (2 * b - a); + b = c; + } + mask >>= 1; + } + return a; + } +} diff --git a/crates/integration/contracts/flipper.sol b/crates/integration/contracts/flipper.sol index 269c489..13acfe4 100644 --- a/crates/integration/contracts/flipper.sol +++ b/crates/integration/contracts/flipper.sol @@ -4,7 +4,7 @@ pragma solidity ^0.8.24; contract Flipper { bool coin; - function flip() public payable { + function flip() public { coin = !coin; } } diff --git a/crates/integration/src/lib.rs b/crates/integration/src/lib.rs index 4eb3757..31b70af 100644 --- a/crates/integration/src/lib.rs +++ b/crates/integration/src/lib.rs @@ -32,6 +32,33 @@ mod tests { use crate::mock_runtime::{self, State}; + #[test] + fn fibonacci() { + sol!( + #[derive(Debug, PartialEq, Eq)] + contract Fibonacci { + function fib3(uint n) public pure returns (uint); + } + ); + + for contract in ["FibonacciIterative", "FibonacciRecursive", "FibonacciBinet"] { + let code = crate::compile_blob(contract, include_str!("../contracts/Fibonacci.sol")); + + let parameter = U256::from(6); + let input = Fibonacci::fib3Call::new((parameter,)).abi_encode(); + + let state = State::new(input); + let (instance, export) = mock_runtime::prepare(&code, None); + let state = crate::mock_runtime::call(state, &instance, export); + + assert_eq!(state.output.flags, 0); + + let received = U256::from_be_bytes::<32>(state.output.data.try_into().unwrap()); + let expected = U256::from(8); + assert_eq!(received, expected); + } + } + #[test] fn flipper() { let code = crate::compile_blob("Flipper", include_str!("../contracts/flipper.sol")); @@ -75,7 +102,7 @@ mod tests { hasher.update(param); let expected = hasher.finalize(); let received = FixedBytes::<32>::from_slice(&state.output.data); - assert_eq!(expected, received); + assert_eq!(received, expected); } #[test]