Skip to content

Commit

Permalink
Merge pull request #54 from SundaeSwap-finance/pi/SSW-101-datum-size-…
Browse files Browse the repository at this point in the history
…minUTXO

Resolve SSW-101
  • Loading branch information
Quantumplation authored Mar 5, 2024
2 parents ad7183c + 2d912b3 commit c65928e
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 12 deletions.
10 changes: 6 additions & 4 deletions lib/tests/examples/ex_settings.ak
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@ use types/settings.{SettingsDatum}
use aiken/transaction.{Input, Output, InlineDatum}
use tests/examples/ex_shared.{print_example, script_address, mk_output_reference}

pub const example_settings_admin = #"725011d2c296eb3341e159b6c5c6991de11e81062b95108c9aa024ad"

pub fn mk_valid_settings_datum(
scoopers: List<ByteArray>,
) -> SettingsDatum {
SettingsDatum {
settings_admin: multisig.Signature(
#"725011d2c296eb3341e159b6c5c6991de11e81062b95108c9aa024ad",
example_settings_admin,
),
metadata_admin: Address(
VerificationKeyCredential(
Expand All @@ -20,7 +22,7 @@ pub fn mk_valid_settings_datum(
None,
),
treasury_admin: multisig.Signature(
#"725011d2c296eb3341e159b6c5c6991de11e81062b95108c9aa024ad",
example_settings_admin,
),
treasury_address: Address(
VerificationKeyCredential(
Expand All @@ -32,7 +34,7 @@ pub fn mk_valid_settings_datum(
authorized_scoopers: Some(scoopers),
authorized_staking_keys: [
VerificationKeyCredential(
#"725011d2c296eb3341e159b6c5c6991de11e81062b95108c9aa024ad"
example_settings_admin,
),
],
base_fee: 0,
Expand Down Expand Up @@ -70,7 +72,7 @@ pub fn mk_valid_settings_input(
test example_settings_datum() {
print_example(
cbor.serialise(mk_valid_settings_datum([
#"725011d2c296eb3341e159b6c5c6991de11e81062b95108c9aa024ad",
example_settings_admin,
])),
)
}
Expand Down
10 changes: 5 additions & 5 deletions validators/settings.ak
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,11 @@ validator(protocol_boot_utxo: OutputReference) {
expect output_datum: SettingsDatum = output_datum

// We check that the value on the input and output are equal, to ensure the settings NFT gets paid back into the output
// TODO: should we allow the ADA to change, just in case the minUTXO changes? that would allow us to add or reclaim
// ADA if minUTXO changed
// We compare `without_lovelace` to leave full freedom for ADA to be added/removed as the minUTXO requirement changes
// Note that this can only be spent by the SettingsAdmin or TreasuryAdmin, so we won't leak a small amount of ADA to arbitrary users
// Also, it is not expected that the ADA ever be more than the minUTXO cost, so this doesn't expose hundreds of ADA (for example) to the treasury admin
let value_not_changed =
own_output.value == own_input.value
value.without_lovelace(own_output.value) == value.without_lovelace(own_input.value)

// Make sure we don't mint anything, otherwise someone might mint another settings token
let no_mint =
Expand Down Expand Up @@ -135,5 +136,4 @@ validator(protocol_boot_utxo: OutputReference) {
pays_to_settings_script,
}
}
}

}
92 changes: 89 additions & 3 deletions validators/tests/settings.ak
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,18 @@ use aiken/transaction.{InlineDatum, NoDatum, OutputReference, TransactionId}
use aiken/transaction/credential.{VerificationKeyCredential, Address, from_script}
use aiken/transaction/value
use sundae/multisig
use types/settings.{SettingsDatum, settings_nft_name}
use types/settings.{SettingsDatum, SettingsAdminUpdate, settings_nft_name}
use tx_util/builder.{
add_asset_to_tx_output,
build_txn_context,
mint_assets,
add_tx_input,
add_tx_output,
new_tx_output,
new_tx_input,
with_asset_of_tx_input,
add_asset_to_tx_output,
mint_assets
}
use tests/examples/ex_settings.{example_settings_admin}
use settings as settings_validator

fn test_mint_settings(settings_nfts_count: Int) {
Expand Down Expand Up @@ -93,4 +94,89 @@ fn mk_valid_settings_datum(
pool_creation_fee: 0,
extensions: Void,
}
}

// Test that we can spend the settings NFT and do a no-op change, except for a new ada lovelace rider value
test test_spend_settings_change_ada_rider() {
let settings_nft_policy = #"01"
let first_settings_utxo = OutputReference { transaction_id: TransactionId { hash: #"01"}, output_index: 0 }
let first_settings_rider = 2_000_000
let first_settings = new_tx_input(
first_settings_utxo.transaction_id.hash,
from_script(settings_nft_policy),
first_settings_rider,
InlineDatum(mk_valid_settings_datum([])),
) |> with_asset_of_tx_input(value.from_asset(settings_nft_policy, settings_nft_name, 1))

let protocol_boot_utxo = OutputReference { transaction_id: TransactionId { hash: #"00"}, output_index: 0 }
let second_settings_datum = mk_valid_settings_datum([])

let second_settings_redeemer = SettingsAdminUpdate

let second_settings_output = new_tx_output(
from_script(settings_nft_policy),
first_settings_rider+1,
InlineDatum(second_settings_datum)
) |> add_asset_to_tx_output(value.from_asset(settings_nft_policy, settings_nft_name, 1))
let ctx =
interval.between(1, 2)
|> build_txn_context()
|> add_tx_input(first_settings)
|> add_tx_output(second_settings_output)
|> builder.add_signatory(example_settings_admin)
|> builder.spend(first_settings.output_reference)

let second_settings = settings_validator.spend(protocol_boot_utxo, second_settings_datum, second_settings_redeemer, ctx)
second_settings
}

// Test that we can spend the settings NFT and CAN'T change a non-ADA value while changing rider
test test_spend_settings_change_value() fail {
let settings_nft_policy = #"01"
let first_settings_utxo = OutputReference { transaction_id: TransactionId { hash: #"01"}, output_index: 0 }
let first_settings_rider = 2_000_000
let first_settings = new_tx_input(
first_settings_utxo.transaction_id.hash,
from_script(settings_nft_policy),
first_settings_rider,
InlineDatum(mk_valid_settings_datum([])),
) |> with_asset_of_tx_input(value.from_asset(settings_nft_policy, settings_nft_name, 1))

let protocol_boot_utxo = OutputReference { transaction_id: TransactionId { hash: #"00"}, output_index: 0 }
let second_settings_datum = mk_valid_settings_datum([])

let second_settings_redeemer = SettingsAdminUpdate

let second_settings_output = new_tx_output(
from_script(settings_nft_policy),
first_settings_rider+1,
InlineDatum(second_settings_datum)
) |> add_asset_to_tx_output(value.from_asset(settings_nft_policy, settings_nft_name, 1))

let junk_policy = "junk policy"
let junk_name = "junk name"
let junk_utxo = OutputReference { transaction_id: TransactionId { hash: #"99"}, output_index: 0 }
let junk_input = new_tx_input(
junk_utxo.transaction_id.hash,
from_script(junk_policy),
1,
InlineDatum(Void)) |> with_asset_of_tx_input(value.from_asset(junk_policy, junk_name, 1))

let junk_output = new_tx_output(
from_script(junk_policy),
1,
InlineDatum(Void)
) |> add_asset_to_tx_output(value.from_asset(junk_policy, junk_name, 1))
let ctx =
interval.between(1, 2)
|> build_txn_context()
|> add_tx_input(first_settings)
|> add_tx_input(junk_input)
|> add_tx_output(second_settings_output)
|> add_tx_output(junk_output)
|> builder.add_signatory(example_settings_admin)
|> builder.spend(first_settings.output_reference)

let second_settings = settings_validator.spend(protocol_boot_utxo, second_settings_datum, second_settings_redeemer, ctx)
second_settings
}

0 comments on commit c65928e

Please sign in to comment.