Skip to content

Vault #220

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 84 commits into from
Apr 16, 2025
Merged

Vault #220

merged 84 commits into from
Apr 16, 2025

Conversation

markspanbroek
Copy link
Member

@markspanbroek markspanbroek commented Feb 6, 2025

Adds a Vault contract, that allows funds to be locked up for a certain amount of time. These funds can be transferred, burned or even flow over time to other addresses.

Follows the design from codex-research/design/contract-deployment

Requires #219 to be merged first.

@markspanbroek
Copy link
Member Author

Added functionality to have multiple accounts for an account holder inside a fund. This ensures that in the codex marketplace we keep funds for the client and for each slot separate, even though some providers may choose to fill multiple slots, or a client might decide to fill a slot in the storage contract itself.

@markspanbroek markspanbroek force-pushed the vault branch 2 times, most recently from 3049325 to 724670b Compare February 24, 2025 15:13
@markspanbroek
Copy link
Member Author

Replaced 🔥 burnFund() with ❄️ freezeFund().
Freezing a fund stops all flows and disallows any further changes to the fund until it unlocks.

Copy link
Collaborator

@emizzle emizzle left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Really great job Mark! Huge effort 💪 🙌

This was quite a lot to go through. I used the implementation branch (master...vault-integration#diff-5973808e32384782b5978a63e85b893b67d634be8aa42001f0ef480f189a0688R179) to get a better understanding of how some of the functionality relates to the Marketplace.

One question:
When we discussed freezing the vault, we discussed that it would not be able to be unfrozen by a controlling party. In this implementation, unfreezing happens after some time has elapsed, making the funds withdrawable again. Is the idea here that in the case of an attack, the vaults would all be locked in some way with a very long expiry?

Copy link
Member

@AuHau AuHau left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work Mark! 🎉

I don't see any big problem with the general approach and design here. My only concern is the usage of the uint128 for the balance tracking. See my comment bellow.

This is big PR, so this is just my first iteration of review. Will do more later on.

@markspanbroek
Copy link
Member Author

Thanks for the good feedback @AuHau and @emizzle. I think I addressed most of the naming concerns.

One question:
When we discussed freezing the vault, we discussed that it would not be able to be unfrozen by a controlling party. In this implementation, unfreezing happens after some time has elapsed, making the funds withdrawable again. Is the idea here that in the case of an attack, the vaults would all be locked in some way with a very long expiry?

The freezeFund() function only freezes a single fund, meaning that there can be no transfers or flows anymore until the fund unlocks and withdrawal can happen. This can happen in the marketplace when a storage request fails. The freezing functionality that we discussed and wrote down in the design document is different. This is about freezing the entire contract, allowing only withdrawals, in an emergency situation where our contracts are under attack. This is implemented by the vault through the use of the Pausable contract.

Base automatically changed from update-solidity to master March 4, 2025 08:33
markspanbroek added a commit to codex-storage/codex-research that referenced this pull request Mar 10, 2025
Updates to the API of the Vault contract as worked on in codex-storage/codex-contracts-eth#220

Most important changes:
- token transfers are much more restricted in the vault, improving its safety
- when a storage request fails, only the providers at fault are punished, the rest are not
-  when a storage request fails, the client is only reimbursed for the remaining time in the contract
-  no longer possible for the marketplace to request one final storage proof before allowing withdrawal
-  repair reward is temporarily stored with the client's funds while slot is free, and not yet filled; this could lead to client withdrawing repair rewards when slots are free when the request ends
Copy link
Member

@AuHau AuHau left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another round of comments.

Comment on lines +243 to +245
function unpause() public onlyOwner {
_unpause();
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Didn't we discuss that it would be possible to only freeze the contract without the possibility to unfreeze it?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We discussed it, but didn't come to a conclusion yet. It may be nice to be able to pause the vault while working on a critical fix for the marketplace contract, and then unpause it once the fix is in place.

let account

beforeEach(async function () {
account = await vault.encodeAccountId(holder.address, randomBytes(12))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why a random account? Wouldn't a fixed account be better?

Copy link
Member Author

@markspanbroek markspanbroek Apr 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any account discriminator should work for these tests

expect(await vault.getLockExpiry(fund)).to.equal(expiry)
})

it("does not allow a lock with expiry past maximum", async function () {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about setting the expiry/maximum into the past?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is currently allowed, although not very useful

Comment on lines +34 to +36
/// Indicates that a locked fund is frozen. Flows have stopped, nothing is
/// allowed until the fund unlocks.
Frozen,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why Frozen also stop the flows? I could imagine a use-case, where you deposit and set up all the funds in the Locked stage and then you would just want to make it "immutable" to just wait until funds get unlocked and prevent any changes to the setting. Frozen could almost be used for it, except it stops the flows...

Honestly, I would rather specify this using the functions that freeze the funds eq. having freezeFund() (will not stop the flows) and freezeFundsAndStopFlows() (will freeze funds and stop flows).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I see that freezing can be interpreted in more than one way. I chose this, because for the marketplace we need the interpretation that the balances do not change after this point. I would suggest to revisit this when needed.

markspanbroek and others added 2 commits April 16, 2025 11:05
Reason: update() is too generic, and can easily be
interpreted as changing the on-chain state, whereas
it actually updates the in-memory struct.

Co-Authored-By: Eric <5089238+emizzle@users.noreply.github.com>
Co-Authored-By: Adam Uhlíř <adam@uhlir.dev>
Co-Authored-By: Adam Uhlíř <adam@uhlir.dev>
@markspanbroek markspanbroek merged commit e49abc4 into master Apr 16, 2025
4 checks passed
@markspanbroek markspanbroek deleted the vault branch April 16, 2025 09:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants