Transferring PURSE
Last updated
Last updated
The upgraded PURSE contract has a number of functions to transfer PURSE as ERC20 or ERC721.
PURSE transfers that are ERC20 related remain mostly the same prior to the upgrade, however there are some important updates. Some of the updates concerning PURSE transfers are: transferFrom
is now a function that can be used for both ERC20 and ERC721, depending on the value that is passed as the valueOrId_
argument; and erc20TransferFrom
and erc721TransferFrom
are functions added as wrappers to emulate what a pure transferFrom
would behave in standard ERC20 and ERC721 tokens. A detailed breakdown for each transfer related function is provided below.
During PURSE ERC20 transfers, the contract will first try to use up all the PURSE in an address’s Inactive Balance. Once the Inactive Balance is depleted, the contract will start to use the PURSE in the address’s Active Balance - which represents the PURSE NFTs owned by the address. However, this will result in NFTs being removed from the address to offset the deficit in the Inactive Balance; and each removal of an NFT would result in an increment of 1,000,000 PURSE in the Inactive Balance, but a reduction of 1,000,000 PURSE in the Active Balance. (See as an example)
When a PURSE NFT is successfully transferred from one address to another - regardless of whether the recipient is an Externally Owned Account (EOA) or a smart contract, the ownership of the NFT is transferred to the recipient, and the Active Balances of both the sender and the recipient are updated accordingly. Since 1 PURSE NFT is represented by 1,000,000 PURSE ERC20, the sender’s Active Balance will be deducted by this amount while the recipient’s Active Balance will be increased by the same amount; and the Inactive Balance for both parties will remain unchanged since this is an ERC721 transfer.
When a PURSE NFT is transferred, the transfer is technically moving 1,000,000 PURSE from the sender to the recipient; but instead of the change in balance being accounted for in the Inactive Balance, it is accounted for in the Active Balance. Since the Total Balance is the sum of the Inactive Balance and Active Balance, this change will also be reflected in the current Total Balance of PURSE for both the sender and the recipient.
With 1,000,000 PURSE in his balance, Bob decides to mint a PURSE NFT. After minting, Bob’s Total Balance (TB) of PURSE is still 1,000,000 PURSE, but the breakdown of his total balance will now be: Inactive Balance (IB) = 0 PURSE and Active Balance (AB) = 1,000,000 PURSE.
Bob determines that he wants to return Alice the PURSE she sent him, but he only has one PURSE NFT in his address which represents all the PURSE in his current balance. Bob transfers the PURSE NFT to Alice, and now his balance of PURSE is completely zero. On the other hand, Alice’s balance has now increased by 1,000,000 PURSE, and she has one PURSE NFT in her address.
Recall at the end of , Alice’s total balance was 900,000 PURSE, where IB = 900,000 and AB = 0, and she didn't have a PURSE NFT. Now after receiving Bob’s PURSE NFT, Alice’s TB is now 1,900,000 PURSE, where IB = 900,000 PURSE and AB = 1,000,000 PURSE, and she has one PURSE NFT.\
The following are functions that can be used to transfer PURSE as an ERC20 token:
transfer
Pure ERC20 transfer
.
value_
is strictly treated as ERC20 amounts, even if the amount is a valid ERC721 token id. Assumes the operator is attempting to transfer as ERC20.
Updates the Inactive Balance of both the msg.sender
and to_
.
Returns a boolean
value indicating operation success.
transferFrom
Function for mixed transfers using either erc20TransferFrom
or erc721TransferFrom
, depending on valueOrId_
.
The function assumes that the operator is attempting to transfer as ERC721 if valueOrId_
is a valid ERC721 token id.
If valueOrId_
is not a valid ERC721 token id, it transfers as ERC20.
Returns a boolean
value indicating operation success.
erc20TransferFrom
Function for ERC20 transferFrom
.
Moves value_
amount of PURSE from from_
to to_
using the allowance mechanism. Updates only the Inactive Balance of both from_
and to_
.
value_
is deducted from the operator’s allowance.
Updates the Inactive Balance of both from_
and to_
.
Returns a boolean
value indicating operation success.
The following are functions that can be used to transfer PURSE as an ERC721 token:
transferFrom
Function for mixed transfers using either erc20TransferFrom
or erc721TransferFrom
, depending on valueOrId_
.
The function assumes that the operator is attempting to transfer as ERC721 if valueOrId_
is a valid ERC721 token id.
If valueOrId_
is not a valid ERC721 token id, it transfers as ERC20.
Returns a boolean
value indicating operation success.
Use of safeTransferFrom
is preferred and highly recommended over transferFrom
for ERC721 transfers.
erc721TransferFrom
Function for ERC721 `transferFrom`.
Transfers `id_` from `from_` to `to_`.
Both `from_` and `to_` cannot be the zero address.
`id_` must be owned by `from_`
If the operator is not `from_`, the operator must be approved to move the token by either `approve` or `setApprovalForAll`.
Updates both Inactive Balance and Active Balance of both `from_` and `to_`.
IMPORTANT: The operator is responsible for confirming that the recipient (to_
) is capable of receiving ERC721 tokens or else they may be permanently lost. Recommend to use safeTransferFrom
but the operator must understand that this adds an external call to the recipient which may create a reentrancy vulnerability.
safeTransferFrom
Safely transfers id_
token from from_
to to_
, checking first that contract recipients are aware of the ERC721 protocol and returns the magic value to the PURSE contract. This prevents tokens from being locked permanently.
Same as erc721TransferFrom
.
If to_
is a smart contract, it must implement IERC721Receiver.onERC721Received
, which is called upon a safe transfer.
safeTransferFrom
(with additional bytes
)
Overloaded function of safeTransferFrom
.
Takes an additional bytes argument: data_
.
The following table provides recommendations for the different transfer functions to execute based on the circumstances of the transfer.
Send PURSE as ERC20
transfer(address,uint256)
transferFrom(address,address,uint256)
Send PURSE as ERC721
safeTransferFrom(address,address,uint256)
Send PURSE as ERC721, with additional data
safeTransferFrom(address,address,uint256,bytes)
Send PURSE as ERC721, without recipient check
transferFrom(address,address,uint256)