Skip to content

Latest commit

 

History

History
171 lines (118 loc) · 5.13 KB

tip-157.md

File metadata and controls

171 lines (118 loc) · 5.13 KB
tip: 157
title: Freeze instructions in TVM
author: [email protected]
status: Final
type: Standards Track
category: VM
created: 2020-06-03

Simple Summary

To provide freeze related operations in TVM.

Abstract

Freeze & Unfreeze operation in system contract are introduced, smart contract can freeze and get resource from the system.

Motivation

Common user can freeze TRX to get resource, such as TRON power, bandwidth, energy. However, none privatekey accounts, like smart contracts, can't get resources from the staking mechanism. This TIP provide instructions to get resource, so that smart contracts can provide tron power for voting and also provide resource delegation to others.

Specification

New instructions in TVM

0xd5: FREEZE

The FREEZE takes 3 operands pop up from stack:

receiverAddress: account address to receive generated resource.

freezeAmount: amount to freeze in SUN.

resourceType: 0 as bandwidth, 1 as energy.

If operation succeed, push 1 to stack, otherwise push 0 to stack.

0xd6: UNFREEZE

The UNFREEZE takes 2 operands pop up from stack.

receiverAddress: account address which received resource.

resourceType: 0 as bandwidth, 1 as energy.

If operation succeed, push 1 to stack, otherwise push 0 to stack.

0xd7: FREEZEEXPIRETIME

The FREEZEEXPIRETIME takes 2 operands pop up from stack.

targetAddress: target account address.

resourceType: 0 as bandwidth, 1 as energy.

If operation succeed, push the expire time to stack, otherwise push 0 to stack.

Notice

For FREEZE or UNFREEZE, if receiverAddress == contractAddress, means that contract freeze or unfreeze for itself.

For FREEZE or UNFREEZE, if receiverAddress != contractAddress, receiverAddress must not be address of contract.

For FREEZE, automatically active non-existent account and consume additional energy.

For FREEZE, amount must not be less than 1 TRX = 10e6 SUN.

For FREEZEEXPIRETIME, return value is in seconds.

Solidity example

// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.5.17 || ^0.6.2 || ^0.7.0 || ^0.8.0;

contract TestFreeze {

    /**
     * @dev Contract can accept value while creating.
     */
    constructor() public payable {}

    /**
     * @dev Freeze `amount` balance of contract to get resource for `receiver` 
     * which type is `res` (0 for bandwidth, 1 for energy).
     *
     * Below situations can cause `revert` excepiton:
     * 1. `amount` is greater than long.max_value or contract balance.
     * 2. `amount` is less than 10e6 sun (1 trx).
     * 3. `res` is not zero or one.
     * 4. `receiver` is contract address (exclude this contract).
     * 
     * Caution: 
     * 1. Balance freezing is also at least three days.
     * 2. Contract can never use its bandwidth or energy.
     * 3. If `receiver` account does not exist, the operation will create it.
     * 4. If contract still has delegated frozen balance for other account,
     *    suicide can not be excuted and throw a revert exception.
     */
    function freezeBalance(address payable receiver, uint amount, uint res) payable external {
        receiver.freeze(amount, res);
    }

    /**
     * @dev Unfreeze specific balance to get corresponding balance.You can use 
     * `receiver' and 'res'  (0 for bandwidth, 1 for energy) parameters to 
     * unfreeze specific balance.
     *
     * Below situations can cause `revert` excepiton:
     * 1. `res` is not zero or one.
     * 2. Frozen relationship between contract and `receiver` does not exist.
     * 3. It is not time to unfreeze the specific balance.
     *
     * Caution:
     * 1. If contract does not have enough tron power to support its votes after unfreezing
     *    this part of frozen balance, the operation will auto clear votes and extract
     *    reward to contract allowance.
     */
    function unfreezeBalance(address payable receiver, uint res) external {
        receiver.unfreeze(res);
    }
    
    /**
     * @dev Query the timestamp which the specific balance can be unfreezed.
     */
    function queryExpireTime(address payable target, uint res) external view returns(uint) {
        return target.freezeExpireTime(res);
    }

    /**
     * @dev Execute self destruct and transfer all balance and asset of contract to target address.
     *
     * Below situations can cause `revert` excepiton:
     * 1. There are still delegated frozen balance for other account address.
     */
    function killme(address payable target) external {
        selfdestruct(target);
    }
}

Notice

receiver or target must have address payable type, means that calling those methods on non-payable address will cause a complier error.

Rationale

Tier

FREEZE tier.ExtTier

UNFREEZE tier.ExtTier

FREEZEEXPIRETIME tier.ExtTier

Energy cost

FREEZE: 20000 energy

UNFREEZE: 20000 energy

FREEZEEXPIRETIME: 50 energy

New account while freezing: 25000 energy

Selfdestruct

If contract still has unfreezed balance for others, selfdestruct will case REVERT exception.

Unfreezed balance for contract itself will be unfreezed and transfer to inheritor`s balance after selfdesturct executed.