Skip to content
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 by Bors] - Allow vaults to spend received funds #5840

Closed
wants to merge 12 commits into from

Conversation

lrettig
Copy link
Member

@lrettig lrettig commented Apr 11, 2024

Motivation

Fixes an oversight in genvm implementation: vesting vaults are unable to spend received coins.

Description

Adds a Balance() method to host/context to allow genvm templates to read current account balance, then updates vault spending arithmetic accordingly.

Test Plan

Added tests in genvm/templates/vault/vault_test.go

TODO

  • Explain motivation or link existing issue(s)
  • Test changes and document test plan
  • Update documentation as needed
  • Update changelog as needed

@lrettig lrettig force-pushed the vaults-received-coins branch 2 times, most recently from 999682f to 5edb642 Compare April 12, 2024 19:00
Copy link

codecov bot commented Apr 12, 2024

Codecov Report

Attention: Patch coverage is 92.85714% with 1 lines in your changes are missing coverage. Please review.

Project coverage is 80.4%. Comparing base (3e9b225) to head (9a26373).

Files Patch % Lines
genvm/templates/vault/vault.go 90.0% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##           develop   #5840   +/-   ##
=======================================
  Coverage     80.4%   80.4%           
=======================================
  Files          285     285           
  Lines        29510   29514    +4     
=======================================
+ Hits         23750   23756    +6     
+ Misses        4161    4159    -2     
  Partials      1599    1599           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@lrettig lrettig marked this pull request as ready for review April 12, 2024 20:48
@lrettig
Copy link
Member Author

lrettig commented Apr 12, 2024

thanks @fasmat. let's get a second review on this one since the code path is pretty critical.

@lrettig lrettig marked this pull request as draft April 14, 2024 16:33
@lrettig
Copy link
Member Author

lrettig commented Apr 14, 2024

@dshulyak pointed out that there's nothing currently preventing a misconfigured vault (with, say, an actual balance less than the TotalAmount) from being spawned. I addressed this, please see the latest commits.

This however raises the question - do we want to allow Spawning of misconfigured/invalid Vaults in the first place? Examples would be an insufficient balance, or VestingStart > VestingEnd. With the code as it stands there's no harm in allowing them, and I've written the logic here in such a way that the funds in the vault can still be spent. We may also want to prevent Spawn of any Vault other than the genesis Vaults to prevent this sort of issue.

If VestingStart > VestingEnd, no Spend can occur until VestingStart layer, at which point the TotalAmount becomes available.
If account balance < unvested portion of TotalAmount, no Spend can occur, but this can always be remedied by sending more coins to the account.

@lrettig lrettig marked this pull request as ready for review April 14, 2024 18:23
@poszu
Copy link
Contributor

poszu commented Apr 16, 2024

This however raises the question - do we want to allow Spawning of misconfigured/invalid Vaults in the first place? Examples would be an insufficient balance, or VestingStart > VestingEnd. With the code as it stands there's no harm in allowing them, and I've written the logic here in such a way that the funds in the vault can still be spent. We may also want to prevent Spawn of any Vault other than the genesis Vaults to prevent this sort of issue.

I prefer when objects in invalid state cannot exist in the first place rather than have to have checks around in the logic because the checks are easy to miss or get wrong.

If VestingStart > VestingEnd, no Spend can occur until VestingStart layer, at which point the TotalAmount becomes available. If account balance < unvested portion of TotalAmount, no Spend can occur, but this can always be remedied by sending more coins to the account.

I think VestingStart > VestingEnd is not possible because of this check:

if spawn.VestingEnd.Before(spawn.VestingStart) {
return nil, fmt.Errorf("vesting end %s should be atleast equal to start %s",
spawn.VestingEnd, spawn.VestingStart)
}

However, VestingStart == VestingEnd is possible, in which case the code in

vested.Div(vested, new(big.Int).SetUint64(uint64(v.VestingEnd.Difference(v.VestingStart))))
would crash (division by zero).

@lrettig
Copy link
Member Author

lrettig commented Apr 16, 2024

I prefer when objects in invalid state cannot exist in the first place rather than have to have checks around in the logic because the checks are easy to miss or get wrong.

Makes sense. But the question is orthogonal to the fixes in this PR. Let's get this merged and then address that question separately.

However, VestingStart == VestingEnd is possible, in which case the code in

vested.Div(vested, new(big.Int).SetUint64(uint64(v.VestingEnd.Difference(v.VestingStart))))

would crash (division by zero).

Actually division by zero is impossible here. If VestingStart == VestingEnd then one of these two conditionals will be triggered first:

if lid.Before(v.VestingStart) {
return 0
}
if !lid.Before(v.VestingEnd) {
return v.TotalAmount
}

Note that there's already a test for this:

{
desc: "vest start equals end",
start: 2,
end: 2,
lid: 1,
total: 1000,
spend: 1,
expect: ErrAmountNotAvailable,
},

I'll add a comment in the code to this effect.

Host context must return remote account balance
Ensure that vault can spend received coins, and that coins are spent out
of vault (remote) wallet not principal wallet
Add exactly vault initial balance in genesis
(Continue to add more coins for other types of accounts)
Need to give vest account a little more gas to account for larger tx
size for multisig tests
Adds a new error type and allows these txs to be failed rather than
crashing the node with a panic
It doesn't make sense to configure a vault this way but there's no harm
in doing so and we don't forbid Spawn, so allow Spend here
h/t @poszu

Remove unused DrainedSoFar property
Make comment clearer
@lrettig
Copy link
Member Author

lrettig commented Apr 17, 2024

bors merge

spacemesh-bors bot pushed a commit that referenced this pull request Apr 17, 2024
## Motivation

Fixes an oversight in genvm implementation: vesting vaults are unable to spend received coins.
@spacemesh-bors
Copy link

Build failed:

  • ci-status

@lrettig
Copy link
Member Author

lrettig commented Apr 17, 2024

bors merge

spacemesh-bors bot pushed a commit that referenced this pull request Apr 17, 2024
## Motivation

Fixes an oversight in genvm implementation: vesting vaults are unable to spend received coins.
@spacemesh-bors
Copy link

Build failed:

@lrettig
Copy link
Member Author

lrettig commented Apr 17, 2024

bors merge

spacemesh-bors bot pushed a commit that referenced this pull request Apr 17, 2024
## Motivation

Fixes an oversight in genvm implementation: vesting vaults are unable to spend received coins.
@spacemesh-bors
Copy link

Pull request successfully merged into develop.

Build succeeded:

@spacemesh-bors spacemesh-bors bot changed the title Allow vaults to spend received funds [Merged by Bors] - Allow vaults to spend received funds Apr 17, 2024
@spacemesh-bors spacemesh-bors bot closed this Apr 17, 2024
@spacemesh-bors spacemesh-bors bot deleted the vaults-received-coins branch April 17, 2024 20:25
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.

None yet

3 participants