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

Reward Interception at the Cosmos Layer for Lien Payoff #4466

Closed
JimLarson opened this issue Feb 5, 2022 · 5 comments
Closed

Reward Interception at the Cosmos Layer for Lien Payoff #4466

JimLarson opened this issue Feb 5, 2022 · 5 comments
Assignees
Labels
BLD-Boost Issues relating to the BLD Boost contract and UI bug Something isn't working cosmic-swingset package: cosmic-swingset enhancement New feature or request Inter-protocol Overarching Inter Protocol vaults_triage DO NOT USE

Comments

@JimLarson
Copy link
Contributor

What is the Problem Being Solved?

Issue #4244 gives the problem of needing to use RUN rewards from staking to first pay off any Lien debt. In fact, the whole Lien concept, where liened BLD is not liquidated, is predicated on being able to take control of a slice of the reward stream.

But implementing this reward interception at the JS level is difficult, as it cannot happen atomically with reward distribution. Automation at the JS level can quickly schedule an after-the-fact transfer of the reward out of the account, but there would be a race with the user attempting to do the same thing.

Instead, if we implemented the interception at the Cosmos level, the interception would be atomic with the reward, leaving no room for a race with the user. But there would be a price - the need to mirror the debt state at the Cosmos level.

Description of the Design

Distribution hooks

As part of the clawback vesting work (agoric-labs/cosmos-sdk PR#155), we added a feature for hooks into the distribution module:

type DistributionHooks interface {
	// AllowWithdrawAddr tells whether to honor the delegation withdraw
	// address associated with the address (if any). The distribution
	// keeper will call this before each reward withdrawal.
	// If multiple distribution hooks are set, then any of them may
	// disallow the withdraw address.
	AllowWithdrawAddr(ctx sdk.Context, delAddr sdk.AccAddress) bool

	// AfterDelegationReward is called after the reward has been transferred the address.
	AfterDelegationReward(ctx sdk.Context, delAddr, withdrawAddr sdk.AccAddress, reward sdk.Coins)
}

There is an existing hook that's used for clawback vesting accounts. It disables the ability to use a separate withdrawal address, then calculates the vested/unvested ratio of the staked tokens (preferring to make as much as possible vested), then adjusts the vesting schedule to have the unvested portion of the reward vest in proportion to the existing remaining vesting amount.

We shouldn't make the existing hook lien-aware, since it's part of cosmos-sdk. Fortunately, you can register multiple hooks with the distribution module, and I believe a new lien-aware hook would compose with the vesting hook in either order.

Account state model and reward calculations

Previous work on liens identified the 3 dimensions of activity of an account: staking, lockup, and liens. (See spec.

Since we need to prohibit liens on unvested funds (#4332), vesting fits into the lien dimension, where there will now be three states:

  • Liened: currently encumbered by a lien. Cannot be transferred. Also, the liened amount is not reduced by slashing, so an account can actually go "in the red" with an unsatisfied lien liability.
  • Unvested: funds still subject to clawback (the other "vesting" accounts implement only the lockup dimension), and so also encumbered.
  • Free: the remainder of the account balance, if any. Could still be encumbered on the staking or lockup dimensions.

After slashing, we have different behavior depending on what happens next:

  • Transfer out, reward withdrawal, or additional grant: the slashed amount is characterized as unvested first, then vested. The liened amount is not affected by slashing, but slashing could remove some of the funds encumbered by the lien.
  • Clawback: the slashed amount is characterized as vested first, then unvested. This could reduce the funds backing the lien. (See Clawback vs lien vs slashing #4463.)

For reward distribution, we have a different calculation:

  • First account for any slashing as unvested first, then free, then the funds backing the lien.
  • Then account for the bonded amount as liened first, then free, then unvested. The reward is then divided proportional to these ratios.

The new distribution hook for liens will make this calculation and then transfer out the liened share of the reward, up at a maximum of the remaining debt. Since the liened amount is invisible to the distribution hook for vesting, they should be able to run in either order.

Cosmos-side state and bridge protocol

The above calculation needs to know the remaining debt associated with any lien, and reduce it when it confiscates the rewards. It must track the funds it has placed into its own module account and on behalf of which liened account. Then it must make these confiscated rewards available to

So we need the following synchronous bridge messages from JS to golang:

  • set or modify the getRUN "collateral" and loan amounts;
  • query for current state and maximum lien-able BLD remaining (takes vesting into account);

and the following async messages from golang to JS:

  • notification of reward confiscation.

Additionally, we must allow JS to transfer funds out of the Cosmos-level module account, which is best done by extending or duplicating the logic in x/vbank to make it behave like a purse, or add analogous bridge messages.

Relation to standalone lien module

Fortunately, the above mechanisms are already largely implemented in the paused standalone line of credit module (#3991).

I'd estimate about 13 story points to complete the work for the purposes here, depending on the details of the JS-Golang API.

Security Considerations

Test Plan

@JimLarson JimLarson added enhancement New feature or request cosmic-swingset package: cosmic-swingset Inter-protocol Overarching Inter Protocol BLD-Boost Issues relating to the BLD Boost contract and UI MN-1 labels Feb 5, 2022
@JimLarson JimLarson added this to the Mainnet: Phase 1 - RUN Protocol milestone Feb 5, 2022
@JimLarson JimLarson self-assigned this Feb 5, 2022
@Tartuffo Tartuffo removed the MN-1 label Feb 7, 2022
@Tartuffo Tartuffo removed this from the Mainnet: Phase 1 - RUN Protocol milestone Feb 8, 2022
@Tartuffo
Copy link
Contributor

@dckc for your input please.

@JimLarson
Copy link
Contributor Author

Tag @dckc

@Tartuffo
Copy link
Contributor

We decided this is how it should be done, so let's do it for MN-1.

@dckc
Copy link
Member

dckc commented Mar 23, 2022

JL: options look like "cron job" or trigger on user action
RG: trigger on user action is the market norm
DC: I like it.

DC: then what do you need from the JS side?
JL: debt as it changes.
DC: interest?
JL: under-reporting debt is OK

JL: burn it or use v-purse?
DC/MF: burn on golang side and tell JS how much; then JS can update golang on debtAmount
JL: we'll have to take care with money supply. privilege to burn here is something we haven't done yet.

MF: escrow in v-bank? stability pool?
RG: this is a burn situation.

RG: does runStake do stability pool stuff?
CH: it should

@Tartuffo Tartuffo removed this from the Mainnet 1 RC0 milestone Sep 21, 2022
@rowgraus rowgraus added the vaults_triage DO NOT USE label Jan 11, 2023
@aj-agoric aj-agoric added the bug Something isn't working label Feb 5, 2024
@JimLarson
Copy link
Contributor Author

Liens support has been removed and is not a near-term goal. Closing now, but can reopen if we want the feature in the future.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
BLD-Boost Issues relating to the BLD Boost contract and UI bug Something isn't working cosmic-swingset package: cosmic-swingset enhancement New feature or request Inter-protocol Overarching Inter Protocol vaults_triage DO NOT USE
Projects
None yet
Development

No branches or pull requests

6 participants