diff --git a/README.md b/README.md index 168aea6..7ce6f1e 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,3 @@ -> This repo is a work in progress. -

@@ -12,6 +10,13 @@ A template repository for building a huff based smart contract project with Foun For more information on using foundry with solidity, check out the [foundry-starter-kit](https://github.com/smartcontractkit/foundry-starter-kit) + Implementation of the following 2 Chainlink features using the [Foundry](https://book.getfoundry.sh/getting-started/installation.html) & [Huff](https://huff.sh/) development environment: + - [Chainlink Price Feeds](https://docs.chain.link/docs/using-chainlink-reference-contracts) + - [Chainlink Keepers](https://docs.chain.link/docs/chainlink-keepers/introduction/) + +# Table Of Contents + +- [Table Of Contents](#table-of-contents) - [Getting Started](#getting-started) - [Requirements](#requirements) - [Quickstart](#quickstart) diff --git a/src/KeepersConsumer.huff b/src/KeepersConsumer.huff index 31686f3..7e1ec87 100644 --- a/src/KeepersConsumer.huff +++ b/src/KeepersConsumer.huff @@ -7,7 +7,6 @@ #define function performUpkeep(bytes) nonpayable returns() #define function lastTimeStamp() view returns(uint256) - /* Overriden Constants */ #define constant INTERVAL = 0x0000000000000000000000000000000000000000 // Will be overrided at deploy time @@ -74,9 +73,7 @@ // First, we make sure checkupkeep is good CHECK_UPKEEP() // [0x00, 0x20, 0x00, time_comparison] pop pop pop // [time_comparison] - // 0x01 // [0x01, time_comparison] - // eq // [time_comparison == 1] - iszero + iszero // [time_comparison == 0] // Revert if checkUpkeep is false! fail jumpi diff --git a/src/VRFConsumerV2.huff b/src/VRFConsumerV2.huff new file mode 100644 index 0000000..0f41561 --- /dev/null +++ b/src/VRFConsumerV2.huff @@ -0,0 +1,4 @@ +// SPDX-License-Identifier: MIT +// TODO + + diff --git a/src/interfaces/ArrayPlay.sol b/src/interfaces/ArrayPlay.sol new file mode 100644 index 0000000..dfa896b --- /dev/null +++ b/src/interfaces/ArrayPlay.sol @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.7; + +interface ArrayPlay { + function readFromArray(uint256) external view returns (uint256); + + function storeInArray(uint256) external; +} diff --git a/src/minimal/ArrayPlay.huff b/src/minimal/ArrayPlay.huff new file mode 100644 index 0000000..0dc7497 --- /dev/null +++ b/src/minimal/ArrayPlay.huff @@ -0,0 +1,56 @@ +/* Interface */ +#define function readFromArray(uint256) view returns (uint256) // a uint256[] array we are reading from +#define function storeInArray(uint256) nonpayable returns() // a uint256[] array we are reading from + +/* Storage Slots */ +#define constant ARRAY_STARTING_SLOT = FREE_STORAGE_POINTER() + +/* Macros */ +#define macro READ_FROM_FIXED_ARRAY() = takes (0) returns (0) { + 0x04 calldataload // [array index to read from] array index should be 0 + iszero // [index == 0] + success jumpi // [iszero_result] + + 0x00 0x00 revert + + success: + [ARRAY_STARTING_SLOT] // [ARRAY_STARTING_SLOT, iszero_result] + 0x00 mstore // [iszero_result] // Memory now has the starting slot + 0x20 0x00 // [offset, size, iszero_result] + sha3 // [HashedStorageSlot, iszero_result] // sha3 reads from memory based on the offset & size given + sload // [value_in_array, iszero_result] + + 0x00 mstore // [iszero_result] // Memory now has the starting slot + 0x20 0x00 return +} + +// We are going to use a fixed-length array of size 1 +// This makes it easy to code lol +// If you're feeling frisky, you can try to implement: +// 1. A solidity sytle dynamic array +// 2. A vyper style bounded dynamic array (I'd love to see this one.) +#define macro STORE_UINT256() = takes(0) returns(0) { + 0x04 calldataload // [uint256 to store] + [ARRAY_STARTING_SLOT] // [StartingSlot, uint256 to store] + 0x00 mstore // [uint256 to store] // Memory now has the starting slot + 0x20 0x00 // [offset, size, Argument] + sha3 // [HashedStorageSlot, Argument] // sha3 reads from memory based on the offset & size given + sstore // [] +} + +/* Special Macros */ +#define macro MAIN() = takes (0) returns (0) { + // Identify which function is being called. + 0x00 calldataload 0xE0 shr + + dup1 __FUNC_SIG("readFromArray(uint256)") eq readFromArray jumpi + dup1 __FUNC_SIG("storeInArray(uint256)") eq storeInArray jumpi + + readFromArray: + READ_FROM_FIXED_ARRAY() + + storeInArray: + STORE_UINT256() +} + +// 0xb2ea7c8400000000000000000000000000000000 diff --git a/test/minimal/ArrayTest.t.sol b/test/minimal/ArrayTest.t.sol new file mode 100644 index 0000000..b6327ad --- /dev/null +++ b/test/minimal/ArrayTest.t.sol @@ -0,0 +1,26 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.15; + +import "foundry-huff/HuffDeployer.sol"; +import "forge-std/Test.sol"; +import "../../src/interfaces/ArrayPlay.sol"; + +contract ArrayPlayTest is Test { + ArrayPlay public arrayPlay; + + function setUp() public { + arrayPlay = ArrayPlay( + HuffDeployer.config().deploy("minimal/ArrayPlay") + ); + } + + function testGetArrayAtPositionZero() public { + uint256 valToStore = 77; + arrayPlay.storeInArray(valToStore); + + uint256 readValue = arrayPlay.readFromArray(0); + assert(readValue == valToStore); + } + + function testGetArrayAtPositionTwo() public {} +}