Skip to content

Commit

Permalink
Merge pull request #80 from SundaeSwap-finance/rrruko/manage-stake-sc…
Browse files Browse the repository at this point in the history
…ript

"Manage" pool stake script
  • Loading branch information
Quantumplation authored Apr 12, 2024
2 parents db5185c + 3694074 commit d4896d1
Show file tree
Hide file tree
Showing 10 changed files with 344 additions and 202 deletions.
8 changes: 8 additions & 0 deletions build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,17 @@ aiken blueprint apply -v settings.mint $PROTOCOL_BOOT_UTXO > tmp
mv tmp plutus.json

SETTINGS_SCRIPT_HASH="581c$(aiken blueprint policy -v settings.mint)"
aiken blueprint apply -v pool.manage $SETTINGS_SCRIPT_HASH > tmp
mv tmp plutus.json

MANAGE_STAKE_SCRIPT_HASH="581c$(aiken blueprint policy -v pool.manage)"
aiken blueprint apply -v pool.spend $MANAGE_STAKE_SCRIPT_HASH > tmp
mv tmp plutus.json
aiken blueprint apply -v pool.spend $SETTINGS_SCRIPT_HASH > tmp
mv tmp plutus.json

aiken blueprint apply -v pool.mint $MANAGE_STAKE_SCRIPT_HASH > tmp
mv tmp plutus.json
aiken blueprint apply -v pool.mint $SETTINGS_SCRIPT_HASH > tmp
mv tmp plutus.json

Expand Down
6 changes: 3 additions & 3 deletions lib/tests/examples/ex_pool.ak
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use types/pool.{PoolDatum, PoolRedeemer, PoolMintRedeemer, PoolScoop, WithdrawFees, CreatePool}
use types/pool.{PoolDatum, PoolRedeemer, PoolMintRedeemer, PoolScoop, ManageRedeemer, CreatePool, WithdrawFees}
use tests/examples/ex_shared.{print_example}

fn mk_pool_datum() -> PoolDatum {
Expand Down Expand Up @@ -33,8 +33,8 @@ test example_pool_scoop_redeemer() {
print_example(mk_pool_scoop())
}

pub fn mk_withdraw_fees_redeemer() -> PoolRedeemer {
WithdrawFees { amount: 100, treasury_output: 1 }
pub fn mk_withdraw_fees_redeemer() -> ManageRedeemer {
WithdrawFees { amount: 100, treasury_output: 1, pool_input: 0 }
}

test example_pool_withdraw_fees_redeemer() {
Expand Down
23 changes: 12 additions & 11 deletions lib/types/pool.ak
Original file line number Diff line number Diff line change
Expand Up @@ -58,17 +58,9 @@ pub type PoolRedeemer {
/// Much of the complexity of the protocol comes from ensuring this list is processed both efficiently and safely.
input_order: List<(Int, Option<SignedStrategyExecution>, Int)>,
}
/// Withdraw the earned protocol fees into the treasury
WithdrawFees {
/// The amount of earned protocol fees to withdraw
/// Note that we *don't* have to withdraw everything, to allow the minUTXO amount to be left behind on exotic pools.
amount: Int,
/// The index in the transaction outputs that corresponds to the treasury address
/// We do this to efficiently skip to that output,
/// and it is safe to do so because that output must be to the treasury address from the settings datum
treasury_output: Int,
}
UpdatePoolFees
/// Withdraw the earned protocol fees into the treasury, or update the pool
/// fees
Manage
}

/// We use the pool mint script for two different purposes
Expand Down Expand Up @@ -97,3 +89,12 @@ pub type PoolMintRedeemer {
/// to burn the pool NFT (when permitted by the spending validator)
BurnPool { identifier: Ident }
}

pub type ManageRedeemer {
WithdrawFees {
amount: Int,
treasury_output: Int,
pool_input: Int,
}
UpdatePoolFees { pool_input: Int, }
}
80 changes: 56 additions & 24 deletions lucid/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ function settingsDatum(poolStakeHash: string, userPkh: string): string {
],
authorizedStakingKeys: [
{
VKeyCredential: { bytes: poolStakeHash },
SCredential: { bytes: poolStakeHash },
}
],
baseFee: 1000000n,
Expand Down Expand Up @@ -120,13 +120,15 @@ async function listOrder(lucid: Lucid, scripts: Scripts, userPkh: string, assets
},
scooperFee: scooperFee,
destination: {
address: {
paymentCredential: {
VKeyCredential: { bytes: userPkh },
Fixed: {
address: {
paymentCredential: {
VKeyCredential: { bytes: userPkh },
},
stakeCredential: null,
},
stakeCredential: null,
datum: "NoDatum",
},
datum: "NoDatum",
},
order: {
Swap: {
Expand Down Expand Up @@ -508,7 +510,9 @@ async function mintPool(scripts: Scripts, lucid: Lucid, userAddress: Address, se
identifier: toHex(poolId),
assets: assets,
circulatingLp: liq,
feesPer10Thousand: fees,
bidFeesPer10Thousand: fees,
askFeesPer10Thousand: fees,
feeManager: null,
marketOpen: marketOpen || 0n,
feeFinalized: marketOpen || 0n,
protocolFees: 2_000_000n,
Expand Down Expand Up @@ -536,6 +540,17 @@ async function mintPool(scripts: Scripts, lucid: Lucid, userAddress: Address, se
const poolMintRedeemerBytes = Data.to(poolMintRedeemer, types.PoolMintRedeemer);
const poolDatumBytes = Data.to(newPoolDatum, types.PoolDatum);

const poolAddress = (new Utils(lucid)).credentialToAddress(
{
type: "Script",
hash: scripts.poolScriptHash,
},
{
type: "Script",
hash: scripts.poolStakeHash,
}
);

console.log("value: ");
console.log(poolValue);
console.log("newPoolDatum: ");
Expand All @@ -544,6 +559,8 @@ async function mintPool(scripts: Scripts, lucid: Lucid, userAddress: Address, se
console.log(poolMintRedeemerBytes);
console.log("settings datum: ");
console.log(settings.datum);
console.log("pool address: ");
console.log(poolAddress);
console.log("-------");
console.log("seed: ", seed);
const tx = lucid.newTx()
Expand All @@ -554,15 +571,19 @@ async function mintPool(scripts: Scripts, lucid: Lucid, userAddress: Address, se
}, poolMintRedeemerBytes)
.readFrom([...references, settings])
.collectFrom([seed])
.payToContract(scripts.poolAddress, { inline: poolDatumBytes }, poolValue)
.payToContract(poolAddress, { inline: poolDatumBytes }, poolValue)
.payToAddress(userAddress, {
"lovelace": 2_000_000n,
[toUnit(scripts.poolPolicyId, poolLqNameHex)]: liq,
})
.payToAddress(userAddress, {
"lovelace": 2_000_000n,
[toUnit(scripts.poolPolicyId, poolRefNameHex)]: 1n,
});
.payToAddressWithData(
userAddress,
{ inline: "d87980" },
{
"lovelace": 2_000_000n,
[toUnit(scripts.poolPolicyId, poolRefNameHex)]: 1n,
}
);

const str = await tx.toString();
console.log("building tx: " + str);
Expand Down Expand Up @@ -644,8 +665,8 @@ async function testMintPool(lucid: Lucid, emulator: Emulator, scripts: Scripts,
const settings = settingsUtxos[0];

const minted = await mintPool(scripts, lucid, userAddress, settings, [refUtxo], assets, seed, 1_000_000_000n, 1_000_000_000n, [5n, 5n]);
await emulator.awaitTx(minted.mintedHash);
console.log("Minted a pool, hash: " + minted.mintedHash);
await emulator.awaitTx(minted.poolMintedHash);
console.log("Minted a pool, hash: " + minted.poolMintedHash);
return minted;
}

Expand Down Expand Up @@ -739,16 +760,16 @@ async function executeOrder(poolABL: ABL, poolDatum: types.PoolDatum, order: UTx
let res: ABL = { a: 0n, b: 0n, liq: 0n };
if ("Swap" in orderDatum.order) {
if (orderDatum.order.Swap.offer[0] + orderDatum.order.Swap.offer[1] == poolCoinA) {
[res, poolABL] = doSwap(Coin.CoinA, orderDatum.order.Swap.offer[2], poolDatum.feesPer10Thousand, poolABL);
[res, poolABL] = doSwap(Coin.CoinA, orderDatum.order.Swap.offer[2], poolDatum.bidFeesPer10Thousand, poolABL);
console.log("after swapping for coinA, poolABL will be: ");
console.log(poolABL);
} else if (orderDatum.order.Swap.offer[0] + orderDatum.order.Swap.offer[1] == poolCoinB) {
[res, poolABL] = doSwap(Coin.CoinB, orderDatum.order.Swap.offer[2], poolDatum.feesPer10Thousand, poolABL);
[res, poolABL] = doSwap(Coin.CoinB, orderDatum.order.Swap.offer[2], poolDatum.askFeesPer10Thousand, poolABL);
} else {
throw new Error("Order does not appear to match the pool");
}
}
const dest = await fromOrderDatumAddress(orderDatum.destination.address);
const dest = await fromOrderDatumAddress(orderDatum.destination.Fixed.address);
return [poolABL, {
abl: res,
destination: dest,
Expand Down Expand Up @@ -828,9 +849,9 @@ async function scoopPool(scripts: Scripts, lucid: Lucid, userAddress: Address, s
toSpend.push(...orderUtxos);
toSpend.sort((a, b) => a.txHash == b.txHash ? a.outputIndex - b.outputIndex : (a.txHash < b.txHash ? -1 : 1));
for (let e of toSpend) {
if (e.address == scripts.poolAddress) {
if (getAddressDetails(e.address).paymentCredential.hash == scripts.poolScriptHash) {
tx.collectFrom([e], redeemerData);
} else if (e.address == scripts.orderAddress) {
} else if (getAddressDetails(e.address).paymentCredential.hash == scripts.orderScriptHash) {
tx.collectFrom([e], Data.to(orderScoopRedeemer, types.OrderRedeemer));
} else {
tx.collectFrom([e]);
Expand All @@ -856,7 +877,7 @@ async function scoopPool(scripts: Scripts, lucid: Lucid, userAddress: Address, s
.addSigner(userAddress)
.withdraw(scripts.steakAddress, 0n, "00")

.payToContract(scripts.poolAddress, { inline: newPoolDatum }, {
.payToContract(targetPool.address, { inline: newPoolDatum }, {
"lovelace":
newPoolABL.a +
poolDatum.protocolFees,
Expand Down Expand Up @@ -920,7 +941,18 @@ async function testScoopPool(lucid: Lucid, emulator: Emulator, scripts: Scripts,
}
const settings = settingsUtxos[0];

let knownPools = await emulator.getUtxos(scripts.poolAddress);
const poolAddress = (new Utils(lucid)).credentialToAddress(
{
type: "Script",
hash: scripts.poolScriptHash,
},
{
type: "Script",
hash: scripts.poolStakeHash,
}
);

let knownPools = await emulator.getUtxos(poolAddress);

let targetPool = null;
for (let knownPool of knownPools) {
Expand Down Expand Up @@ -1060,8 +1092,8 @@ const accounts: any[] = [
];
let emulator = new Emulator(accounts, {
...PROTOCOL_PARAMETERS_DEFAULT,
//maxTxSize: 999999999999,
//maxTxExMem: 999999999999999n,
maxTxSize: 999999999999,
maxTxExMem: 999999999999999n,
});
let lucid = await Lucid.new(emulator);

Expand Down Expand Up @@ -1128,7 +1160,7 @@ emulator.ledger["000000000000000000000000000000000000000000000000000000000000000

const listOrdersChange = emulator.ledger["00000000000000000000000000000000000000000000000000000000000000001"].utxo;

const { listedHash, utxos: orders } =
const { listedHash, utxos: orders } =
await testListOrder(lucid, emulator, scripts, "lovelace", rberry, listOrdersChange, poolId, 40n);

const scoopPoolChange = await findChange(emulator, userAddress);
Expand Down
5 changes: 5 additions & 0 deletions lucid/run.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Make sure to build the aiken scripts first
deno run \
--allow-read \
main.ts \
--scriptsFile ../plutus.json
24 changes: 15 additions & 9 deletions lucid/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,10 +110,17 @@ export const DatumSchema = Data.Enum([
//Data.Object({ InlineDatum: Data.Any() }),
]);

export const DestinationSchema = Data.Object({
address: AddressSchema,
datum: DatumSchema,
});
export const DestinationSchema = Data.Enum([
Data.Object({
Fixed: Data.Object({
address: AddressSchema,
datum: DatumSchema,
}),
}),
Data.Object({
Self: Data.Tuple([]),
}),
]);

export const ExtensionSchema = Data.Enum([
Data.Literal("NoExtension"),
Expand All @@ -139,7 +146,9 @@ export const PoolDatumSchema = Data.Object({
identifier: IdentSchema,
assets: Data.Tuple([AssetClassSchema, AssetClassSchema]),
circulatingLp: Data.Integer(),
feesPer10Thousand: Data.Tuple([Data.Integer(), Data.Integer()]),
bidFeesPer10Thousand: Data.Tuple([Data.Integer(), Data.Integer()]),
askFeesPer10Thousand: Data.Tuple([Data.Integer(), Data.Integer()]),
feeManager: Data.Nullable(MultiSigScriptSchema),
marketOpen: Data.Integer(),
feeFinalized: Data.Integer(),
protocolFees: Data.Integer(),
Expand Down Expand Up @@ -201,10 +210,7 @@ export const PoolSpendRedeemerSchema = Data.Enum([
}),
}),
Data.Object({
WithdrawFees: Data.Object({
amount: Data.Integer(),
treasuryOutput: Data.Integer(),
}),
Manage: Data.Tuple([]),
}),
]);

Expand Down
Loading

0 comments on commit d4896d1

Please sign in to comment.