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

Add disbursal saturation to hydra #884

Draft
wants to merge 12 commits into
base: master
Choose a base branch
from
Draft
2 changes: 1 addition & 1 deletion hydra/js/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Find the
In order to update the generated SDK when the rust contract was updated please run:

```
yarn gen:api
yarn api:gen
```

and then update the wrapper code and tests.
Expand Down
53 changes: 53 additions & 0 deletions hydra/js/idl/hydra.json
Original file line number Diff line number Diff line change
Expand Up @@ -701,6 +701,37 @@
}
],
"args": []
},
{
"name": "processSetSaturation",
"accounts": [
{
"name": "authority",
"isMut": false,
"isSigner": true
},
{
"name": "member",
"isMut": false,
"isSigner": false
},
{
"name": "fanout",
"isMut": true,
"isSigner": false
},
{
"name": "membershipAccount",
"isMut": true,
"isSigner": false
}
],
"args": [
{
"name": "saturationLimit",
"type": "u64"
}
]
}
],
"accounts": [
Expand Down Expand Up @@ -766,6 +797,14 @@
"type": {
"option": "u64"
}
},
{
"name": "saturated",
"type": "bool"
},
{
"name": "saturatedMember",
"type": "publicKey"
}
]
}
Expand Down Expand Up @@ -830,6 +869,10 @@
{
"name": "shares",
"type": "u64"
},
{
"name": "saturationLimit",
"type": "u64"
}
]
}
Expand Down Expand Up @@ -1033,6 +1076,16 @@
"code": 6024,
"name": "InvalidCloseAccountDestination",
"msg": "Sending Sol to a SPL token destination will render the sol unusable"
},
{
"code": 6025,
"name": "SaturationNotSupported",
"msg": "Saturation not supported on this membership model"
},
{
"code": 6026,
"name": "SaturatedMember",
"msg": "Unable to distribute shares with member at saturation limit. Redistribute shares to proceed."
}
],
"metadata": {
Expand Down
10 changes: 10 additions & 0 deletions hydra/js/src/generated/accounts/Fanout.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ export type FanoutArgs = {
membershipModel: MembershipModel;
membershipMint: beet.COption<web3.PublicKey>;
totalStakedShares: beet.COption<beet.bignum>;
saturated: boolean;
saturatedMember: web3.PublicKey;
};

const fanoutDiscriminator = [164, 101, 210, 92, 222, 14, 75, 156];
Expand All @@ -54,6 +56,8 @@ export class Fanout implements FanoutArgs {
readonly membershipModel: MembershipModel,
readonly membershipMint: beet.COption<web3.PublicKey>,
readonly totalStakedShares: beet.COption<beet.bignum>,
readonly saturated: boolean,
readonly saturatedMember: web3.PublicKey,
) {}

/**
Expand All @@ -74,6 +78,8 @@ export class Fanout implements FanoutArgs {
args.membershipModel,
args.membershipMint,
args.totalStakedShares,
args.saturated,
args.saturatedMember,
);
}

Expand Down Expand Up @@ -221,6 +227,8 @@ export class Fanout implements FanoutArgs {
membershipModel: 'MembershipModel.' + MembershipModel[this.membershipModel],
membershipMint: this.membershipMint,
totalStakedShares: this.totalStakedShares,
saturated: this.saturated,
saturatedMember: this.saturatedMember.toBase58(),
};
}
}
Expand Down Expand Up @@ -250,6 +258,8 @@ export const fanoutBeet = new beet.FixableBeetStruct<
['membershipModel', membershipModelBeet],
['membershipMint', beet.coption(beetSolana.publicKey)],
['totalStakedShares', beet.coption(beet.u64)],
['saturated', beet.bool],
['saturatedMember', beetSolana.publicKey],
],
Fanout.fromArgs,
'Fanout',
Expand Down
15 changes: 15 additions & 0 deletions hydra/js/src/generated/accounts/FanoutMembershipVoucher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export type FanoutMembershipVoucherArgs = {
bumpSeed: number;
membershipKey: web3.PublicKey;
shares: beet.bignum;
saturationLimit: beet.bignum;
};

const fanoutMembershipVoucherDiscriminator = [185, 62, 74, 60, 105, 158, 178, 125];
Expand All @@ -39,6 +40,7 @@ export class FanoutMembershipVoucher implements FanoutMembershipVoucherArgs {
readonly bumpSeed: number,
readonly membershipKey: web3.PublicKey,
readonly shares: beet.bignum,
readonly saturationLimit: beet.bignum,
) {}

/**
Expand All @@ -52,6 +54,7 @@ export class FanoutMembershipVoucher implements FanoutMembershipVoucherArgs {
args.bumpSeed,
args.membershipKey,
args.shares,
args.saturationLimit,
);
}

Expand Down Expand Up @@ -176,6 +179,17 @@ export class FanoutMembershipVoucher implements FanoutMembershipVoucherArgs {
}
return x;
})(),
saturationLimit: (() => {
const x = <{ toNumber: () => number }>this.saturationLimit;
if (typeof x.toNumber === 'function') {
try {
return x.toNumber();
} catch (_) {
return x;
}
}
return x;
})(),
};
}
}
Expand All @@ -198,6 +212,7 @@ export const fanoutMembershipVoucherBeet = new beet.BeetStruct<
['bumpSeed', beet.u8],
['membershipKey', beetSolana.publicKey],
['shares', beet.u64],
['saturationLimit', beet.u64],
],
FanoutMembershipVoucher.fromArgs,
'FanoutMembershipVoucher',
Expand Down
42 changes: 42 additions & 0 deletions hydra/js/src/generated/errors/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -528,6 +528,48 @@ createErrorFromNameLookup.set(
() => new InvalidCloseAccountDestinationError(),
);

/**
* SaturationNotSupported: 'Saturation not supported on this membership model'
*
* @category Errors
* @category generated
*/
export class SaturationNotSupportedError extends Error {
readonly code: number = 0x1789;
readonly name: string = 'SaturationNotSupported';
constructor() {
super('Saturation not supported on this membership model');
if (typeof Error.captureStackTrace === 'function') {
Error.captureStackTrace(this, SaturationNotSupportedError);
}
}
}

createErrorFromCodeLookup.set(0x1789, () => new SaturationNotSupportedError());
createErrorFromNameLookup.set('SaturationNotSupported', () => new SaturationNotSupportedError());

/**
* SaturatedMember: 'Unable to distribute shares with member at saturation limit. Redistribute shares to proceed.'
*
* @category Errors
* @category generated
*/
export class SaturatedMemberError extends Error {
readonly code: number = 0x178a;
readonly name: string = 'SaturatedMember';
constructor() {
super(
'Unable to distribute shares with member at saturation limit. Redistribute shares to proceed.',
);
if (typeof Error.captureStackTrace === 'function') {
Error.captureStackTrace(this, SaturatedMemberError);
}
}
}

createErrorFromCodeLookup.set(0x178a, () => new SaturatedMemberError());
createErrorFromNameLookup.set('SaturatedMember', () => new SaturatedMemberError());

/**
* Attempts to resolve a custom program error from the provided error code.
* @category Errors
Expand Down
1 change: 1 addition & 0 deletions hydra/js/src/generated/instructions/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export * from './processInit';
export * from './processInitForMint';
export * from './processRemoveMember';
export * from './processSetForTokenMemberStake';
export * from './processSetSaturation';
export * from './processSetTokenMemberStake';
export * from './processSignMetadata';
export * from './processTransferShares';
Expand Down
104 changes: 104 additions & 0 deletions hydra/js/src/generated/instructions/processSetSaturation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
/**
* This code was GENERATED using the solita package.
* Please DO NOT EDIT THIS FILE, instead rerun solita to update it or write a wrapper to add functionality.
*
* See: https://github.com/metaplex-foundation/solita
*/

import * as beet from '@metaplex-foundation/beet';
import * as web3 from '@solana/web3.js';

/**
* @category Instructions
* @category ProcessSetSaturation
* @category generated
*/
export type ProcessSetSaturationInstructionArgs = {
saturationLimit: beet.bignum;
};
/**
* @category Instructions
* @category ProcessSetSaturation
* @category generated
*/
export const processSetSaturationStruct = new beet.BeetArgsStruct<
ProcessSetSaturationInstructionArgs & {
instructionDiscriminator: number[] /* size: 8 */;
}
>(
[
['instructionDiscriminator', beet.uniformFixedSizeArray(beet.u8, 8)],
['saturationLimit', beet.u64],
],
'ProcessSetSaturationInstructionArgs',
);
/**
* Accounts required by the _processSetSaturation_ instruction
*
* @property [**signer**] authority
* @property [] member
* @property [_writable_] fanout
* @property [_writable_] membershipAccount
* @category Instructions
* @category ProcessSetSaturation
* @category generated
*/
export type ProcessSetSaturationInstructionAccounts = {
authority: web3.PublicKey;
member: web3.PublicKey;
fanout: web3.PublicKey;
membershipAccount: web3.PublicKey;
};

export const processSetSaturationInstructionDiscriminator = [36, 113, 187, 145, 92, 204, 116, 202];

/**
* Creates a _ProcessSetSaturation_ instruction.
*
* @param accounts that will be accessed while the instruction is processed
* @param args to provide as instruction data to the program
*
* @category Instructions
* @category ProcessSetSaturation
* @category generated
*/
export function createProcessSetSaturationInstruction(
accounts: ProcessSetSaturationInstructionAccounts,
args: ProcessSetSaturationInstructionArgs,
) {
const { authority, member, fanout, membershipAccount } = accounts;

const [data] = processSetSaturationStruct.serialize({
instructionDiscriminator: processSetSaturationInstructionDiscriminator,
...args,
});
const keys: web3.AccountMeta[] = [
{
pubkey: authority,
isWritable: false,
isSigner: true,
},
{
pubkey: member,
isWritable: false,
isSigner: false,
},
{
pubkey: fanout,
isWritable: true,
isSigner: false,
},
{
pubkey: membershipAccount,
isWritable: true,
isSigner: false,
},
];

const ix = new web3.TransactionInstruction({
programId: new web3.PublicKey('hyDQ4Nz1eYyegS6JfenyKwKzYxRsCWCriYSAjtzP4Vg'),
keys,
data,
});
return ix;
}
6 changes: 6 additions & 0 deletions hydra/program/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,4 +94,10 @@ pub enum HydraError {

#[msg("Sending Sol to a SPL token destination will render the sol unusable")]
InvalidCloseAccountDestination,

#[msg("Saturation not supported on this membership model")]
SaturationNotSupported,

#[msg("Unable to distribute shares with member at saturation limit. Redistribute shares to proceed.")]
SaturatedMember,
}
7 changes: 7 additions & 0 deletions hydra/program/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,4 +91,11 @@ pub mod hydra {
pub fn process_remove_member(ctx: Context<RemoveMember>) -> Result<()> {
remove_member(ctx)
}

pub fn process_set_saturation(
ctx: Context<SetSaturation>,
saturation_limit: u64,
) -> Result<()> {
set_saturation(ctx, saturation_limit)
}
}
1 change: 1 addition & 0 deletions hydra/program/src/processors/distribute/wallet_member.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ pub fn distribute_for_wallet(
assert_owned_by(&member.to_account_info(), &System::id())?;
assert_membership_model(fanout, MembershipModel::Wallet)?;
assert_shares_distributed(fanout)?;
assert_no_saturation(fanout)?;
if distribute_for_mint {
let membership_key = &ctx.accounts.member.key().clone();
let member = ctx.accounts.member.to_owned();
Expand Down
2 changes: 2 additions & 0 deletions hydra/program/src/processors/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ pub mod add_member;
pub mod distribute;
pub mod init;
pub mod remove_member;
pub mod set_saturation;
pub mod signing;
pub mod stake;
pub mod transfer_shares;
Expand All @@ -16,6 +17,7 @@ pub use self::init::init_for_mint::*;
pub use self::init::init_parent::*;
pub use self::remove_member::process_remove_member::*;
pub use self::remove_member::process_remove_member::*;
pub use self::set_saturation::process_set_saturation::*;
pub use self::signing::sign_metadata::*;
pub use self::stake::set::*;
pub use self::stake::set_for::*;
Expand Down
1 change: 1 addition & 0 deletions hydra/program/src/processors/set_saturation/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub mod process_set_saturation;
Loading