GiverV3.sol
Overview
GiverV3.sol is a smart contract designed to facilitate the controlled distribution of cryptocurrency tokens and native currency within a blockchain environment. It extends an abstract Upgradable contract, enabling the contract code to be upgraded securely. The contract primarily handles sending native currency and tokens (referred to as "currencies") to other addresses, including minting tokens as necessary to fulfill the transfers. It also tracks messages related to its operations and supports the receipt of simple transfers.
Contracts and Inheritance
Upgradable (abstract contract)
Purpose: Provides functionality for secure upgradeability of the contract's code.
Key Functionality:
upgrade(TvmCell newcode): Allows the contract owner to upgrade the contract's code. It validates the caller's public key, accepts the message, commits the transaction, and sets the new code. Then triggers theonCodeUpgrade()hook.onCodeUpgrade() internal virtual: A hook function to handle any necessary logic after an upgrade. It is intended to be overridden by inheriting contracts.
GiverV3 (contract)
Inherits from
Upgradable.Manages sending native currency and tokens to other contracts or addresses.
Contains mechanisms to mint tokens and native currency automatically if the contract's balance is insufficient.
Tracks messages with expiration times.
Detailed Explanation of Contract Components
Constants
MAX_CLEANUP_MSGS(uint8): A constant set to 30, though not actively used in the current implementation.
State Variables
m_messages(mapping(uint256 => uint32)): Stores messages identified by a hash (uint256) mapped to an expiration timestamp (uint32).
Modifiers
Description: Restricts function execution to the contract owner (identified by matching the message public key with the contract's public key).
Usage: Applied to functions requiring owner-only access.
Behavior: Checks the public key and accepts the inbound message.
Events
SentCurrency(address dst, varuint16 value, mapping(uint32 => varuint32))Emitted when tokens and native currency are sent.
SentCurrencyWithFlag(address dst, varuint16 value, mapping(uint32 => varuint32), uint8 flag)Emitted when tokens and native currency are sent with an additional flag parameter.
Functions and Methods
Constructor
Initializes the contract. Currently, it contains no specific initialization logic.
Fallback Function
receive() externalAllows the contract to accept simple transfers of native currency without any data.
sendTransaction
function sendTransaction(address dest, varuint16 value, bool bounce) public pure
Purpose: Sends native currency (
value) to a destination address.Parameters:
dest: The target address to send funds.value: Amount of native currency to send.bounce: Boolean flag indicating whether the transfer should bounce if it fails.
Behavior: Accepts the inbound message and transfers the specified amount to
destwith the given bounce behavior.Example Usage:
sendTransaction(address(0x123...), 1000, true);
sendCurrency
function sendCurrency(address dest, varuint16 value, mapping(uint32 => varuint32) ecc) public pure
Purpose: Sends native currency and multiple token types (
ecc) to a destination address.Parameters:
dest: Destination address.value: Amount of native currency to send.ecc: Mapping of token currency IDs (uint32) to token amounts (varuint32).
Implementation Details:
Checks if token currencies with IDs
1and2exist in theeccmapping.If the contract's balance of these tokens is insufficient, it mints the required difference using external calls (
gosh.mintecc).If the contract's native currency balance is insufficient (less than
value + 1000 vmshell), it mints the difference viagosh.mintshellq.Transfers the native currency and tokens to
destwith bounce disabled and flag set to 1.Emits
SentCurrencyevent.
Example Usage:
mapping(uint32 => varuint32) tokens; tokens[1] = 100; tokens[2] = 50; sendCurrency(address(0xabc...), 2000, tokens);
sendCurrencyWithFlag
function sendCurrencyWithFlag(address dest, varuint16 value, mapping(uint32 => varuint32) ecc, uint8 flag) public pure
Purpose: Similar to
sendCurrencybut allows specifying a custom transfer flag.Parameters:
dest: Destination address.value: Amount of native currency to send.ecc: Mapping of tokens to send.flag: Custom flag to be used in the transfer.
Implementation Details: Same minting and balance checks as
sendCurrency.Emits:
SentCurrencyWithFlagevent.Example Usage:
sendCurrencyWithFlag(address(0xdef...), 3000, tokens, 2);
sendFreeToken
function sendFreeToken(address dest) public pure
Purpose: Sends a fixed amount of tokens and native currency to a destination address as a "free token" drop.
Details:
Mints 50 units of token with currency ID 2.
Sends 10 units of native currency plus the minted tokens.
Checks and mints additional native currency if balance is insufficient.
Transfers with bounce disabled and flag set to 1.
Example Usage:
sendFreeToken(address(0x456...));
getMessages
function getMessages() public view returns (Message[] messages)
Purpose: Returns an array of stored messages with their hash and expiration time.
Returns: Array of
Messagestructs.Message Struct:
hash(uint256): Message identifier.expireAt(uint32): Expiration timestamp.
Usage: Can be called to retrieve all stored message metadata.
onCodeUpgrade
function onCodeUpgrade() internal override {}
Purpose: Overridden from
Upgradablecontract.Behavior: Empty implementation; can be customized to add logic on contract code upgrades.
Important Implementation Details
Minting Logic: Before sending tokens or native currency, the contract checks its balance. If the balance is insufficient, it calls external minting functions (
gosh.minteccfor tokens andgosh.mintshellqfor native currency) to mint the required amounts dynamically.Secure Access: Critical functions use checks on the message sender's public key to ensure only authorized access.
Transfer Flags: Transfers can specify flags which influence the behavior of the transaction in the blockchain environment. This contract uses flags to control bounce behavior and other transfer semantics.
Interaction with Other Components
External Calls:
gosh.mintecc(uint64 amount, uint32 currencyId): Mints tokens of a specified currency.gosh.mintshellq(uint64 amount): Mints native currency.
Currency Balances:
Accesses
address(this).currenciesto check token balances for currency IDs1and2.Uses
address(this).balanceto check native currency balance.
Events:
Emits events to notify external observers of outgoing transfers, enabling tracking and auditing.
The contract is designed to be a utility module that other contracts or users can interact with to receive tokens and native currency, potentially as part of test networks, faucet mechanisms, or reward systems.
Visual Diagram: Class and Method Structure
classDiagram
class Upgradable {
+upgrade()
+onCodeUpgrade()
}
class GiverV3 {
-MAX_CLEANUP_MSGS: uint8
-m_messages: mapping
+sendTransaction()
+sendCurrency()
+sendCurrencyWithFlag()
+sendFreeToken()
+getMessages()
+onCodeUpgrade()
+receive()
}
GiverV3 --|> Upgradable