Skip to content

Commit

Permalink
Small iteration + README
Browse files Browse the repository at this point in the history
  • Loading branch information
Quantumplation committed Feb 13, 2025
1 parent ef89843 commit 17a9761
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 68 deletions.
70 changes: 12 additions & 58 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,65 +1,19 @@
# treasury-funds

Write validators in the `validators` folder, and supporting functions in the `lib` folder using `.ak` as a file extension.
These contracts provide a simple but robust way to manage funds withdrawn from the treasury.

```aiken
validator my_first_validator {
spend(_datum: Option<Data>, _redeemer: Data, _output_reference: Data, _context: Data) {
True
}
}
```
They ensure that the funds cannot be delegated, and cannot be used in governance voting.

## Building
Additionally, the require approval from a set of independent "auditors" for any disbursments,
with the intention that requests for disbursement include a durable link to off-chain invoices
and proof of work completion.

```sh
aiken build
```
Disbursals require a high threshold of consent (ex: unanimous) from the auditors.
However, to minimize the impact of a lost key, funds can be withdrawn with a lower
threshold requirement after a long timeout.

## Configuring
After a longer timeout, or with unanimous consent of the auditors, the funds can be
sent back to the treasury.

**aiken.toml**
```toml
[config.default]
network_id = 41
```

Or, alternatively, write conditional environment modules under `env`.

## Testing

You can write tests in any module using the `test` keyword. For example:

```aiken
use config
test foo() {
config.network_id + 1 == 42
}
```

To run all tests, simply do:

```sh
aiken check
```

To run only tests matching the string `foo`, do:

```sh
aiken check -m foo
```

## Documentation

If you're writing a library, you might want to generate an HTML documentation for it.

Use:

```sh
aiken docs
```

## Resources

Find more on the [Aiken's user manual](https://aiken-lang.org).
The contract can optionally support an initial OTC deal, where the initially withdrawn funds
can be swapped for a stablecoin at an agreed upon price.
27 changes: 17 additions & 10 deletions validators/treasury.ak
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
use aiken/collection/list
use aiken/collection/pairs
use cardano/address.{Credential}
use cardano/assets.{lovelace_of}
use cardano/transaction.{Transaction}
use aiken/collection/pairs
use aiken/collection/list

validator treasury {
spend(_d, _r, _i, _t) {
// TODO
False
}

Expand All @@ -20,19 +21,25 @@ validator treasury {
// the withdrawal, we assert that `account` never occurs in the inputs
// This is slightly less flexible than ensuring the totals carry through, but
// also simpler to reason about
expect None = self.inputs
|> list.find(fn(input) { input.output.address.payment_credential == account })
expect None =
self.inputs
|> list.find(
fn(input) { input.output.address.payment_credential == account },
)

// Sum up the amounts of the withdrawal paid to `account`
// This lets us split the funds across multiple UTxOs for accounting purposes
// but still ensures that the total amount is correct
let output_sum = self.outputs
let output_sum =
self.outputs
|> list.filter(fn(output) { output.address.payment_credential == account })
|> list.map(fn(output) {
// Treasury funds must not be staked
expect None = output.address.stake_credential
lovelace_of(output.value)
})
|> list.map(
fn(output) {
// Treasury funds must not be staked
expect None = output.address.stake_credential
lovelace_of(output.value)
},
)
|> list.reduce(0, +)

// Ensure that the output sum is *at least* the amount
Expand Down

0 comments on commit 17a9761

Please sign in to comment.