Skip to main content

Module sui::funds_accumulator

A module for accumulating funds, i.e. Balance-like types.

use std::ascii;
use std::bcs;
use std::option;
use std::string;
use std::vector;
use sui::accumulator;
use sui::address;
use sui::dynamic_field;
use sui::hex;
use sui::object;
use sui::party;
use sui::transfer;
use sui::tx_context;
use sui::vec_map;

Struct Withdrawal

Allows for withdrawing funds from a given address. The

Withdrawal
can be created in PTBs for the transaction sender, or dynamically from an object via
withdraw_from_object
. The redemption of the funds must be initiated from the module that defines T.

public struct Withdrawal<phantom T: store> has drop
Click to open
Fields
owner: address
The owner of the funds, either an object or a transaction sender
limit: u256
At signing we check the limit <= balance when taking this as a call arg. If this was generated from an object, we cannot check this until redemption.

Constants

Attempted to withdraw more than the maximum value of the underlying integer type.

const EOverflow: u64 = 0;

Attempt to split more than the current limit of a

Withdrawal
.

#[error]
const EInvalidSubLimit: vector<u8> = b"Sub-limit exceeds current withdrawal limit";

Attempted to join two withdrawals with different owners.

#[error]
const EOwnerMismatch: vector<u8> = b"Withdrawal owners do not match";

Function withdrawal_owner

Returns the owner, either a sender's address or an object, of the withdrawal.

public fun withdrawal_owner<T: store>(withdrawal: &sui::funds_accumulator::Withdrawal<T>): address
Click to open
Implementation
public fun withdrawal_owner<T: store>(withdrawal: &Withdrawal<T>): address {
    withdrawal.owner
}

Function withdrawal_limit

Returns the remaining limit of the withdrawal.

public fun withdrawal_limit<T: store>(withdrawal: &sui::funds_accumulator::Withdrawal<T>): u256
Click to open
Implementation
public fun withdrawal_limit<T: store>(withdrawal: &Withdrawal<T>): u256 {
    withdrawal.limit
}

Function withdrawal_split

Split a

Withdrawal
and take a sub-withdrawal from it with the specified sub-limit.

public fun withdrawal_split<T: store>(withdrawal: &mut sui::funds_accumulator::Withdrawal<T>, sub_limit: u256): sui::funds_accumulator::Withdrawal<T>
Click to open
Implementation
public fun withdrawal_split<T: store>(
    withdrawal: &mut Withdrawal<T>,
    sub_limit: u256,
): Withdrawal<T> {
    assert!(withdrawal.limit >= sub_limit, EInvalidSubLimit);
    withdrawal.limit = withdrawal.limit - sub_limit;
    Withdrawal { owner: withdrawal.owner, limit: sub_limit }
}

Function withdrawal_join

Join two withdrawals together, increasing the limit of self by the limit of other. Aborts with

EOwnerMismatch
if the owners are not equal. Aborts with
EOverflow
if the resulting limit would overflow u256.

public fun withdrawal_join<T: store>(withdrawal: &mut sui::funds_accumulator::Withdrawal<T>, other: sui::funds_accumulator::Withdrawal<T>)
Click to open
Implementation
public fun withdrawal_join<T: store>(withdrawal: &mut Withdrawal<T>, other: Withdrawal<T>) {
    assert!(withdrawal.owner == other.owner, EOwnerMismatch);
    assert!(std::u256::max_value!() - withdrawal.limit >= other.limit, EOverflow);
    withdrawal.limit = withdrawal.limit + other.limit;
}

Function redeem

public(package) fun redeem<T: store>(withdrawal: sui::funds_accumulator::Withdrawal<T>): T
Click to open
Implementation
public(package) fun redeem</* internal */ T: store>(withdrawal: Withdrawal<T>): T {
    let Withdrawal { owner, limit: value } = withdrawal;
    withdraw_impl(owner, value)
}

Function withdraw_from_object

public(package) fun withdraw_from_object<T: store>(obj: &mut sui::object::UID, limit: u256): sui::funds_accumulator::Withdrawal<T>
Click to open
Implementation
public(package) fun withdraw_from_object<T: store>(obj: &mut UID, limit: u256): Withdrawal<T> {
    let owner = obj.to_address();
    Withdrawal { owner, limit }
}

Function add_impl

public(package) fun add_impl<T: store>(value: T, recipient: address)
Click to open
Implementation
public(package) fun add_impl<T: store>(value: T, recipient: address) {
    let accumulator = sui::accumulator::accumulator_address<T>(recipient);
    add_to_accumulator_address<T>(accumulator, recipient, value)
}

Function withdraw_impl

fun withdraw_impl<T: store>(owner: address, value: u256): T
Click to open
Implementation
fun withdraw_impl<T: store>(owner: address, value: u256): T {
    let accumulator = sui::accumulator::accumulator_address<T>(owner);
    withdraw_from_accumulator_address<T>(accumulator, owner, value)
}

Function add_to_accumulator_address

fun add_to_accumulator_address<T: store>(accumulator: address, recipient: address, value: T)
Click to open
Implementation
native fun add_to_accumulator_address<T: store>(accumulator: address, recipient: address, value: T);

Function withdraw_from_accumulator_address

fun withdraw_from_accumulator_address<T: store>(accumulator: address, owner: address, value: u256): T
Click to open
Implementation
native fun withdraw_from_accumulator_address<T: store>(
    accumulator: address,
    owner: address,
    value: u256,
): T;

Function create_withdrawal

public(package) fun create_withdrawal<T: store>(owner: address, limit: u256): sui::funds_accumulator::Withdrawal<T>
Click to open
Implementation
public(package) fun create_withdrawal<T: store>(owner: address, limit: u256): Withdrawal<T> {
    Withdrawal { owner, limit }
}