Skip to content

Commit

Permalink
Initial Commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Quantumplation committed Sep 13, 2024
0 parents commit 80dff17
Show file tree
Hide file tree
Showing 6 changed files with 156 additions and 0 deletions.
18 changes: 18 additions & 0 deletions .github/workflows/continuous-integration.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
name: Continuous Integration

on:
push:
branches: ["main"]
pull_request:

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: aiken-lang/setup-aiken@v1
with:
version: v1.1.1
- run: aiken fmt --check
- run: aiken check -D
- run: aiken build
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Aiken compilation artifacts
artifacts/
# Aiken's project working directory
build/
# Aiken's default documentation export
docs/
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# fee-manager

This is a small aiken validator meant to solve two problems:

1) Updating a pool requires spending the pool UTXO, which means in the case of a multsig fee manager, requires really tricky timing.
2) Splitting permission to update the fee manager (the "owner"), and the fees (the "manager")
26 changes: 26 additions & 0 deletions aiken.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# This file was generated by Aiken
# You typically do not need to edit this file

[[requirements]]
name = "aiken-lang/stdlib"
version = "v2.0.0"
source = "github"

[[requirements]]
name = "SundaeSwap-finance/aicone"
version = "42b248e14879b5559d875abff5f0bcc6ff4c83b6"
source = "github"

[[packages]]
name = "aiken-lang/stdlib"
version = "v2.0.0"
requirements = []
source = "github"

[[packages]]
name = "SundaeSwap-finance/aicone"
version = "42b248e14879b5559d875abff5f0bcc6ff4c83b6"
requirements = []
source = "github"

[etags]
23 changes: 23 additions & 0 deletions aiken.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
name = "sundae/fee-manager"
version = "0.0.0"
compiler = "v1.1.1"
plutus = "v3"
license = "Apache-2.0"
description = "Aiken contracts for project 'sundae/fee-manager'"

[repository]
user = "sundae"
project = "fee-manager"
platform = "github"

[[dependencies]]
name = "aiken-lang/stdlib"
version = "v2.0.0"
source = "github"

[[dependencies]]
name = "SundaeSwap-finance/aicone"
version = "42b248e14879b5559d875abff5f0bcc6ff4c83b6"
source = "github"

[config]
77 changes: 77 additions & 0 deletions validators/fee-manager.ak
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
use aiken/crypto.{VerificationKey, Signature}
use aiken/cbor
use aiken/collection/list
use aiken/interval.{intersection}
use cardano/address.{Credential, PaymentCredential}
use cardano/assets.{PolicyId, AssetName}
use cardano/transaction.{Transaction, ValidityRange, find_datum, InlineDatum, DatumHash}
use sundae/multisig

pub type NewFee {
valid_range: ValidityRange,
bid_fees_per_10_thousand: Int,
ask_fees_per_10_thousand: Int,
}

pub type NewFeeManager {
valid_range: ValidityRange,
fee_manager: Option<multisig.MultisigScript>,
}

pub type Redeemer {
UpdateFee { new_fee: NewFee, signatures: List<(VerificationKey, Signature)> }
UpdateFeeManager { new_fee_manager: NewFeeManager, signatures: List<(VerificationKey, Signature)> }
}

// An abbreviated version of the Sundae v3 pool datum
pub type AssetClass = (PolicyId, AssetName)
pub type PoolDatum {
ident: ByteArray,
assets: (AssetClass, AssetClass),
circulating_lp: Int,
bid_fees_per_10_thousand: Int,
ask_fees_per_10_thousand: Int,
fee_manager: Option<multisig.MultisigScript>,
market_open: Int,
protocol_fees: Int,
}

validator fee_manager(
pool_script_hash: PaymentCredential,
owner: multisig.MultisigScript,
manager: multisig.MultisigScript,
) {
withdraw(redeemer: Redeemer, _account: Credential, self: Transaction) {
let Transaction { validity_range, withdrawals, outputs, datums, .. } = self
expect Some(pool_output) = list.find(outputs, fn(o) { o.address.payment_credential == pool_script_hash })
expect Some(pool_datum) = when pool_output.datum is {
InlineDatum(datum) -> Some(datum)
DatumHash(hash) -> find_datum(outputs, datums, hash)
_ -> error "Invalid pool datum"
}
expect PoolDatum { bid_fees_per_10_thousand, ask_fees_per_10_thousand, fee_manager, .. } = pool_datum
when redeemer is {
UpdateFee { new_fee, signatures } -> {
let payload = cbor.serialise(new_fee)
and {
multisig.satisfied_payload(manager, payload, signatures, validity_range, withdrawals),
intersection(validity_range, new_fee.valid_range) == validity_range,
bid_fees_per_10_thousand == new_fee.bid_fees_per_10_thousand,
ask_fees_per_10_thousand == new_fee.ask_fees_per_10_thousand,
}
}
UpdateFeeManager { new_fee_manager, signatures } -> {
let payload = cbor.serialise(new_fee_manager)
and {
multisig.satisfied_payload(owner, payload, signatures, validity_range, withdrawals),
intersection(validity_range, new_fee_manager.valid_range) == validity_range,
fee_manager == new_fee_manager.fee_manager,
}
}
}
}

else(_) {
fail
}
}

0 comments on commit 80dff17

Please sign in to comment.