Skip to content

Commit

Permalink
Merge pull request #73 from SundaeSwap-finance/rrruko/ssw-206-allow-p…
Browse files Browse the repository at this point in the history
…ool-nft-burn

Resolve SSW-206 (allow pool nft burn)
  • Loading branch information
Quantumplation authored Apr 9, 2024
2 parents b6fbf3d + 51d9d36 commit e84cfdf
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 10 deletions.
2 changes: 2 additions & 0 deletions lib/types/pool.ak
Original file line number Diff line number Diff line change
Expand Up @@ -94,4 +94,6 @@ pub type PoolMintRedeemer {
/// This is safe because we validate that the token is paid to the metadata admin
metadata_output: Int
}
/// to burn the pool NFT (when permitted by the spending validator)
BurnPool { identifier: Ident }
}
20 changes: 16 additions & 4 deletions plutus.json

Large diffs are not rendered by default.

11 changes: 10 additions & 1 deletion validators/pool.ak
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use shared.{AssetClass, Ident, spent_output, pool_nft_name, pool_lp_name, count_
use sundae/multisig
use types/pool.{
CreatePool, MintLP, PoolDatum, PoolMintRedeemer, PoolRedeemer, PoolScoop,
WithdrawFees, UpdatePoolFees,
WithdrawFees, UpdatePoolFees, BurnPool,
}
use types/settings.{SettingsDatum, find_settings_datum}
/// The core / base "pooled AMM" script for the SundaeSwap v3 protocol
Expand Down Expand Up @@ -545,6 +545,15 @@ validator(settings_policy_id: PolicyId) {
(ctx.transaction.mint |> value.from_minted_value |> value.quantity_of(own_policy_id, pool_nft_name)) == 0,
}
}
BurnPool(pool_ident) -> {
// Burning an asset is only possible when spending it, so if we enforce
// that the mints consist of exactly 1 burn for the specified pool NFT
// then we can defer to the pool spending validator
expect Mint(own_policy_id) = ctx.purpose
let pool_nft_name = shared.pool_nft_name(pool_ident)
let expected_mint = shared.to_value((own_policy_id, pool_nft_name, -1))
value.from_minted_value(ctx.transaction.mint) == expected_mint
}
}
}
}
Expand Down
66 changes: 61 additions & 5 deletions validators/tests/pool.ak
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ use tests/examples/ex_shared.{
}
use types/order.{Deposit, Destination, Fixed, Self, OrderDatum, Swap}
use types/pool.{
PoolMintRedeemer, CreatePool, PoolDatum, PoolScoop, WithdrawFees, UpdatePoolFees,
PoolMintRedeemer, CreatePool, PoolDatum, PoolScoop, WithdrawFees,
UpdatePoolFees, BurnPool,
}
use calculation/shared.{PoolState} as calc_shared
use types/settings.{SettingsDatum, settings_nft_name}
Expand Down Expand Up @@ -1079,7 +1080,7 @@ test dont_evaporate_pool_test() fail {
}


test attempt_evaporate_pool_test() fail {
test attempt_evaporate_pool_test() {
let withdraw_fees_redeemer = WithdrawFees {
amount: 18_000_000,
treasury_output: 0,
Expand All @@ -1093,7 +1094,7 @@ test attempt_evaporate_pool_test() fail {
(ada_policy_id, ada_asset_name),
(constants.rberry_policy, constants.rberry_asset_name),
),
circulating_lp: 1_000_000_000,
circulating_lp: 0,
bid_fees_per_10_thousand: pool_fees.1st,
ask_fees_per_10_thousand: pool_fees.2nd,
fee_manager: None,
Expand All @@ -1109,8 +1110,6 @@ test attempt_evaporate_pool_test() fail {
InlineDatum(pool_datum))
|> with_asset_of_tx_input(
value.from_asset(constants.pool_script_hash, pool_nft_name, 1)
|> value.add(constants.rberry_policy, constants.rberry_asset_name, 1_000_000_000)
|> value.add(ada_policy_id, ada_asset_name, 1_000_000_000)
)

let treasury_output = new_tx_output(
Expand All @@ -1136,3 +1135,60 @@ test attempt_evaporate_pool_test() fail {
|> builder.spend(pool_input.output_reference)
pool_validator.spend(constants.settings_policy_id, pool_datum, withdraw_fees_redeemer, ctx)
}

test burn_pool() {
let user_addr = wallet_address(constants.payment_key)
let fees = ((5,5),(5,5))
let pool_datum =
PoolDatum {
identifier: constants.pool_ident,
assets: ((ada_policy_id, ada_asset_name), (constants.rberry_policy, constants.rberry_asset_name)),
circulating_lp: 0,
bid_fees_per_10_thousand: fees.1st,
ask_fees_per_10_thousand: fees.2nd,
fee_manager: None,
market_open: 0,
fee_finalized: 0,
protocol_fees: 2_000_000,
}
let pool_nft_name = shared.pool_nft_name(constants.pool_ident)
let pool_address = script_address(constants.pool_script_hash)
let pool_input =
Input {
output_reference: mk_output_reference(0),
output: Output {
address: pool_address,
value: value.from_lovelace(2_000_000)
|> value.add(constants.pool_script_hash, pool_nft_name, 1),
datum: InlineDatum(pool_datum),
reference_script: None,
},
}
let settings_input = {
let Input { output_reference, output } =
mk_valid_settings_input([constants.scooper], 1)
Input { output_reference, output }
}
let change_output =
Output {
address: user_addr,
value: value.from_lovelace(2_000_000),
datum: NoDatum,
reference_script: None,
}

let (_, pool_nft_token, _) = shared.pool_token_names(constants.pool_ident)
let ctx = interval.between(1,2)
|> build_txn_context()
|> mint_assets(constants.pool_script_hash, value.to_minted_value(
value.from_lovelace(0)
|> value.add(constants.pool_script_hash, pool_nft_token, -1)
))
|> add_tx_input(pool_input)
|> add_tx_ref_input(settings_input)
|> add_tx_output(change_output)

let pool_mint_redeemer = BurnPool(constants.pool_ident)
let result = pool_validator.mint(constants.settings_policy_id, pool_mint_redeemer, ctx)
result
}

0 comments on commit e84cfdf

Please sign in to comment.