Ethereum smart contracts for Codex
Go to file
r4bbit 6ae0d85d4e
fix(certora): make vacuous rule pass
The rule `slotIsFailedOrFreeIfRequestHasFailed` currently has violations
as it is vacuous for some functions in the `Marketplace` contract.

The rule being vacuous means that the function on which the rule is
tested either doesn't have a case where the required conditions work (it
reverts), or, in this case, where any given function doesn't have a case
where it reaches the required state change.

There's various functions where this applies because the rule requires
that the request being tested is first any state that is `!= Failed`,
then for any function `f`, when `f` is executed, the required state of
the request is `Failed`.

Prover run that confirms this: https://prover.certora.com/output/6199/82ed96aac5014cb9a7485fc3752fb399?anonymousKey=28c97adbbe14ead331dc8e4b8ed05e94528075a3

There's two options to go about this:

1. Either filter out all functions from the rule where the rule is
   vacuous (this is dangerous because we'd exclude those functions
   entirely from the rule)
2. Or, rewrite the rule such that the requirements are relaxed

This commit implements option 2.
Instead of requiring that the starting request state has to be `!=
Failed`, we simply assert that **if** it **was** not `Failed` and then
**is** `Failed`, the corresponding slot is either failed or free.

Prover run that passes: https://prover.certora.com/output/6199/16fa074bd23146e59c21964c98bbb3e0?anonymousKey=229d721cf35873bed5eae67696eed803ce75fd18
2024-08-27 10:52:56 +02:00
.github/workflows chore(ci): update certora-cli version in CI tasks 2024-08-06 11:01:24 +02:00
certora fix(certora): make vacuous rule pass 2024-08-27 10:52:56 +02:00
contracts fix(certora): make rule for allowed request state changes work again 2024-08-23 14:01:43 +02:00
deploy chore: add `downtimeProduct` configuration parameter (#138) 2024-08-14 15:50:32 +10:00
deployments Add codex_testnet deployment artifacts (#145) 2024-08-07 18:58:31 +03:00
docker chore: Bump Node version (#66) 2023-08-16 11:31:41 +02:00
fuzzing [fuzzing] Use correct hashbang 2023-06-19 14:58:47 +02:00
test feat: adds an optional `payoutAddress` to allow payouts to be paid to separate address (#144) 2024-08-19 17:09:48 +10:00
verifier Add Codex Devnet and Testnet networks (#135) 2024-08-06 08:37:40 +03:00
.editorconfig feat: collateral per slot (#44) 2023-03-08 12:02:34 +01:00
.gitignore Set up certora and implement first rules (#122) 2024-07-24 18:50:18 +02:00
.prettierrc Format using prettier 2022-02-10 07:46:03 +01:00
.solhint.json [style] enforce `_` prefix for private names 2023-01-23 15:10:23 +01:00
.tool-versions Update .tool-versions (#94) 2024-03-20 13:09:32 +00:00
License.md Add license 2022-01-10 11:16:47 +01:00
Readme.md Set up certora and implement first rules (#122) 2024-07-24 18:50:18 +02:00
hardhat.config.js Add Codex Devnet and Testnet networks (#135) 2024-08-06 08:37:40 +03:00
package-lock.json chore: update dependencies (#64) 2023-08-10 13:20:29 +02:00
package.json Set up certora and implement first rules (#122) 2024-07-24 18:50:18 +02:00

Readme.md

Codex Contracts

An experimental implementation of the smart contracts that underlay the Codex storage network. Its goal is to experiment with the rules around the bidding process, the storage contracts, the storage proofs and the host collateral. Neither completeness nor correctness are guaranteed at this moment in time.

Running

To run the tests, execute the following commands:

npm install
npm test

You can also run fuzzing tests (using Echidna) on the contracts:

npm run fuzz

To start a local Ethereum node with the contracts deployed, execute:

npm start

This will create a deployment-localhost.json file containing the addresses of the deployed contracts.

Running the prover

To run the formal verification rules using Certora, first, make sure you have Java (JDK >= 11.0) installed on your machine, and then install the Certora CLI

$ pip install certora-cli

Once that is done the certoraRun command can be used to send CVL specs to the prover.

You can run Certora's specs with the provided npm script:

npm run verify

Overview

The Codex storage network depends on hosts offering storage to clients of the network. The smart contracts in this repository handle interactions between client and hosts as they negotiate and fulfill a contract to store data for a certain amount of time.

When all goes well, the client and hosts perform the following steps:

Client                 Host          Marketplace Contract
  |                     |                      |
  |                                            |
  | --------------- request (1) -------------> |
  |                                            |
  | ----- data (2) ---> |                      |
  |                     |                      |
                        | ----- fill (3) ----> |
                        |                      |
                        | ---- proof (4) ----> |
                        |                      |
                        | ---- proof (4) ----> |
                        |                      |
                        | ---- proof (4) ----> |
                        |                      |
                        | <-- payment (5) ---- |
  1. Client submits a request for storage, containing the size of the data that it wants to store and the length of time it wants to store it
  2. Client makes the data available to hosts
  3. Hosts submit storage proofs to fill slots in the contract
  4. While the storage contract is active, host prove that they are still storing the data by responding to frequent random challenges
  5. At the end of the contract the hosts are paid

Contracts

A storage contract contains of a number of slots. Each of these slots represents an agreement with a storage host to store a part of the data. Hosts that want to offer storage can fill a slot in the contract.

A contract can be negotiated through requests. A request contains the size of the data, the length of time during which it needs to be stored, and a number of slots. It also contains the reward that a client is willing to pay and proof requirements such as how often a proof will need to be submitted by hosts. A random nonce is included to ensure uniqueness among similar requests.

When a new storage contract is created the client immediately pays the entire price of the contract. The payment is only released to the host upon successful completion of the contract.

Collateral

To motivate a host to remain honest, it must put up some collateral before it is allowed to participate in storage contracts. The collateral may not be withdrawn as long as a host is participating in an active storage contract.

Should a host be misbehaving, then its collateral may be reduced by a certain percentage (slashed).

Proofs

Hosts are required to submit frequent proofs while a contract is active. These proofs ensure with a high probability that hosts are still holding on to the data that they were entrusted with.

To ensure that hosts are not able to predict and precalculate proofs, these proofs are based on a random challenge. Currently we use ethereum block hashes to determine two things: 1) whether or not a proof is required at this point in time, and 2) the random challenge for the proof. Although hosts will not be able to predict the exact times at which proofs are required, the frequency of proofs averages out to a value that was set by the client in the request for storage.

Hosts have a small period of time in which they are expected to submit a proof. When that time has expired without seeing a proof, validators are able to point out the lack of proof. If a host misses too many proofs, it results into a slashing of its collateral.

References

To Do

  • Contract repair

    Allow another host to take over a slot in the contract when the original host missed too many proofs.

  • Reward validators

    A validator that points out missed proofs should be compensated for its vigilance and for the gas costs of invoking the smart contract.

  • Analysis and optimization of gas usage