#Standard `freeze()` func for token interface

1 messages · Page 1 of 1 (latest)

round walrus
#

Cross-posting the discussion topic from StellarProtocol repo:
https://github.com/stellar/stellar-protocol/discussions/1652

Multiple DeFi usage scenarios (DAO, trading, bridges, etc.) require locking some amount of tokens on the account/contract balance in order to use them later. A standard approve() function can set the spending token allowance but it cannot ensure that the contract will be able to spend it in the future because a user can transfer/spend/lock these tokens, so the actual balance during the transaction execution might be lower than the allowance. Users can also approve several conflicting allowances to different contracts. This case is similar to the issue addressed by the CAP-3 (Asset-backed offers).

Currently, the only way to overcome this problem is to transfer funds to the contract that will temporary lock them. It's potentially less secure than freezing tokens on the address balance, and not ideal from the tax reporting perspective since transferring funds to some contract even solely for the temporary lockup purpose may be considered a taxable event depending on the jurisdiction.

It would be nice to have a freeze() function in both SAC and standard token interface to provide the ability for the contracts to temporary lock user funds within a pre-approved allowance amount.

GitHub

Multiple DeFi usage scenarios (DAO, trading, bridges, etc.) require locking some amount of tokens on the account/contract balance in order to use them later. A standard approve() function can set t...

#
/// Temporary freeze specified amount of tokens preventing an owner to transfer/burn them.
///
/// # Arguments
///
/// * `from` - The address holding the balance of tokens.
/// * `spender` - The address on behalf of which the tokens are frozen.
/// * `amount` - The tokens to freeze. Cannot be greater than the current token allowance.
/// * `expiration_ledger` - The ledger number where the lockup period expires. 
///    Cannot be less than the current ledger number unless the amount is being set to 0.
///    Cannot be greater than the expiration_ledger specified in the current token allowance.
///    An expired entry (where expiration_ledger < the current ledger number)
///    should be treated as token unlock.
///
/// # Events
///
/// Emits an event with topics `["freeze", from: Address, spender: Address], data = [amount: i128, expiration_ledger: u32]`
fn freeze(env: Env, from: Address, spender: Address, amount: i128, expiration_ledger: u32);

/// Returns the number of tokens frozen by `spender` on the `from` balance.
///
/// # Arguments
///
/// * `from` - The address holding the balance of tokens.
/// * `spender` - The address that have frozen the tokens.
fn frozen(env: Env, from: Address, spender: Address) -> i128;