Immersve Payment Protocol
Contract Module that allows users to deposit and lock funds in order to be able to fund one-time-use Immersve virtual cards.
Extensions
For security reasons, the smart contract implements the following OpenZeppelin Contracts
Proxy
The Smart Contract implements the OpenZeppelin TransparentUpgradeable proxy. Proxy features:
- Security: If any bugs are found, or potential security risks, the Smart Contract can be updated to resolve any potential issues
- Feature Upgradeability: Any new features and bug fixes can be added. The Smart Contract will keep the same state, without the need of expensive migrations
- Stability: Clients interacting with the Smart Contract will always do so through the same proxy address. The proxy will know the current implementation address and will always keep the same state.
More about upgradeable contracts here: https://blog.openzeppelin.com/the-state-of-smart-contract-upgrades/
Proxy URLs
- Polygon (Mainnet): PENDING
- Polygon Mumbai (Testnet): 0xd73c2deE4604a1af3Db4E8E07Cf6Fb798aB77982
Functions
initialize
(address _settlerRole, address payable _settlementAddress, address _tokenSmartContract, uint256 _defaultTimeoutBlocks, uint256 _safetyBlocks) external initializer
Initialize the Smart Contract with the required arguments
_settlerRole
(typeaddress
): The web3 address that will act with theSETTLER
role._settlementAddress
(typeaddress payable
): The web3 address were Locked funds will be sent once a payment is confirmed by Immersve_tokenSmartContract
(typeaddress
): The current network address of the ERC-20 token Smart Contract_defaultTimeoutBlocks
(typeuint256
): Number of blocks in the blockchain that an asset lock will last by default_safetyBlocks
(typeuint256
): Number of blocks on top of the default timeout used to calculate if a Lock is usable or not. Because there might be a delay between a transaction confirmation and the actual use of Locked funds by Immersve, there has to be some safety threshold for Immersve to execute the settlement of funds.
getVersion()
external pure returns(string memory)
Get the current version implementation of the smart contract with a Version number stored in a Solidity Constant. This means that the constant is not saved into the Smart Contract store.
pause()
public onlyRole(PAUSER_ROLE)
Pauses the functionality of the Smart Contract. All the functions marked with the
whenNotPaused
modifier will reject the transaction once a pause is in effect. Only thePAUSER_ROLE
will be able to call this function.
unpause()
public onlyRole(PAUSER_ROLE)
Unpauses the functionality of the Smart Contract. All the functions marked with the
whenNotPaused
modifier will accept the transaction normally. Only thePAUSER_ROLE
will be able to call this function.
setTimeoutBlocks
(uint256 timeoutBlocks) public onlyRole(SETTLER_ROLE)
Set the default timeout for
AssetLockedFund
as described inAsset Locked Funds
section. Only theSETTLER_ROLE
will be able to call this function.
timeoutBlocks
(typeuint256
): Number of blocks for an Asset Lock to be considered expired
setSafetyBlocks
(uint256 timeoutBlocks) public onlyRole(SETTLER_ROLE)
Set the safety block threshold for
AssetLockedFund
as described inAsset Locked Funds
section. Only theSETTLER_ROLE
will be able to call this function.
timeoutBlocks
(typeuint256
): Number of blocks for an Asset Lock to be considered safe to settle
deposit
(uint256 tokenAmount) external whenNotPaused nonReentrant
CardHolders can deposit token funds into the Smart Contract using this function. The funds can either be
locked
orwithdrawn
by the consumer later. Locked funds cannot be withdrawn until the lock expires, or the user revokes the lock with an Immersve token.There is a pre-requisite for this function to work. Because token is an ERC-20 token,
the consumer needs to approve (https://polygonscan.com/token/0x2791bca1f2de4661ed88a30c99a7a9449aa84174#writeProxyContract#F1 token funds
to the Smart Contract public address
tokenAmount
(typeuint256
): token Amount to deposit inethers
format
depositTo
(uint256 tokenAmount, address sender) external whenNotPaused nonReentrant
CardHolders can deposit token funds for a specific address into the Smart Contract using this function. The funds can either be
locked
orwithdrawn
by the consumer later. Locked funds cannot be withdrawn until the lock expires, or the user revokes the lock with an Immersve token.There is a pre-requisite for this function to work. Because token is an ERC-20 token,
the consumer needs to approve (https://polygonscan.com/token/0x2791bca1f2de4661ed88a30c99a7a9449aa84174#writeProxyContract#F1 token funds
to the target sender address for the Smart Contract public address
tokenAmount
(typeuint256
): token Amount to deposit inethers
formataddress
(typeaddress
): Deposit target address
withdraw
(uint256 tokenAmount) external whenNotPaused nonReentrant
CardHolders can withdraw token funds associated to their balance from the Smart Contract using this function. Locked funds cannot be withdrawn until the lock expires, or the user revokes the lock with an Immersve token.
tokenAmount
(typeuint256
): token Amount to withdraw inethers
format
createLockedFund
(uint256 tokenAmount) external whenNotPaused nonReentrant
CardHolders can put a Lock in place for deposited funds so Immersve can authorize the use of a credit card using those locked funds as collateral. The locked funds will be represented with a
AssetLockedFund
struct inside the Smart Contract. When created, a timeout will be put in place for this lock based on the default Timeout Blocks (see [])
tokenAmount
(typeuint256
): token Amount to lock inethers
format
depositAndCreateLockedFund
(uint256 tokenAmount) external whenNotPaused nonReentrant
Similar to deposit but combined with createLockedFund. This function is doing both the deposit and the lock at the same time to save gas fees.
tokenAmount
(typeuint256
): token Amount to deposit inethers
format
depositAndCreateLockedFundFor
(uint256 tokenAmount, address sender) external whenNotPaused nonReentrant
Similar to depositAndCreateLockedFund but the target address is specified as an argument instead of using
msg.sender
tokenAmount
(typeuint256
): token Amount to deposit inethers
format
checkLockedFundPayment
(address sender, uint256 price, uint256 lockedFundId) external view whenNotPaused returns(uint256)
Used by Immersve to check that the locked funds of an Immersve Card payment is currently valid. This function will check that the specified address has enough locked funds for the specified
lockedFundId
and will return the number of blocks that the lock is still valid for.
sender
(typeaddress
): CardHolder Address doing a payment requiring locked funds with Immersveprice
(typeuint256
): token Amount to settle inethers
formatlockedFundId
(typeuint256
): Matching Locked Fund Id (which is linked to a Card) to settle payment being done with an Immersve Credit Card
confirmLockedFundPayment
(address sender, uint256 price, uint256 lockedFundId) external whenNotPaused nonReentrant onlyRole(SETTLER_ROLE)
Used by Immersve to confirm the settlement of an Immersve Card payment. This function will check that the specified address has enough locked funds for the specified
lockedFundId
and will transfer the settlement amount (price
) to the settlement address, specified in theinitialize
function. It releases locked funds. Used for transactions with amount matching locked funds. It can only be called by the SETTLER role
sender
(typeaddress
): CardHolder Address doing a payment requiring locked funds with Immersveprice
(typeuint256
): token Amount to settle inethers
formatlockedFundId
(typeuint256
): Matching Locked Fund Id (which is linked to a Card) to settle payment being done with an Immersve Credit Card
confirmLockedFundPartialPayment
(address sender, uint256 price, uint256 lockedFundId) external whenNotPaused nonReentrant onlyRole(SETTLER_ROLE)
Used by Immersve to confirm the settlement of an Immersve Card payment. This function will check that the specified address has enough locked funds for the specified
lockedFundId
and will transfer the settlement amount (price
) to the settlement address, specified in theinitialize
function. Updates locked funds. Used for partial / incremental transactions (multiple transaction with amount < locked funds). It can only be called by the SETTLER role
sender
(typeaddress
): CardHolder Address doing a payment requiring locked funds with Immersveprice
(typeuint256
): token Amount to settle inethers
formatlockedFundId
(typeuint256
): Matching Locked Fund Id (which is linked to a Card) to settle payment being done with an Immersve Credit Card
getAvailableLockedFundsBalance
(address sender)
Get Available Locked funds for the specified
address
sender
(typeaddress
): CardHolder Address that already did a funds lock
getBalance()
Get the available token balance of the
msg.sender
deposited in the Smart Contract. Balance is not the necessarily the same as locked funds as the former are short lived.
getSenderBalance
(address sender)
Get the available token balance of the specified
sender
argument, deposited in the Smart Contract. Balance is not the necessarily the same as locked funds as the former are short lived.
sender
(typeaddress
): CardHolder Address
getLockedFunds()
Get the
AssetLockedFund
objects of themsg.sender
getSenderLockedFunds
(address sender) onlyRole(SETTLER_ROLE)
Get the
AssetLockedFund
objects of the specifiedsender
argument
sender
(typeaddress
): CardHolder Address that already locked funds at least once
revokeLockedFundMultiSig
(uint256 lockedFundId, uint256 nonce, bytes memory signature) external whenNotPaused nonReentrant
CardHolders will be able to revoke a fund lock using an Immersve signature. Immersve will first check if the funds is being used for a payment on Immersve backend. If the funds are free to release, Immersve will sign a message with a nonce only valid for a
lockedFundId
and the funds will be put back into the CardHolder balance
lockedFundId
(typeuint256
): Id of theAssetLockedFund
to be releasednonce
(typeuint256
): Nonce provided by Immersve API and matches thesignature
signature
(typememory
): String signature provided by Immersve API created with anonce
to avoid replay calls
revokeLockedFund
(address sender, uint256 lockedFundId) external whenNotPaused nonReentrant onlyRole(SETTLER_ROLE)
Function used by Immersve Backend (only SETTLER role can call this function) to revoke an unexpired lock. This could be done if Immersve detect illegal or malicious activity related to the
sender
and prefers to revoke locked fund ids
sender
(typeaddress
): CardHolder Address that already locked funds with the Smart ContractlockedFundId
(typeuint256
): Id of theAssetLockedFund
to be released
Immersve Card E-Commerce Payment Happy Path
- Card Holder locks token funds with Immersve Smart Contract
- Card Holder receives a valid Credit Card to be used for E-Commerce transaction from Immersve
- Card Holder uses the Immersve Card to pay for goods purchased on an E-Commerce platform
- Immersve authorizes the payment with Credit Card network once the locked funds are confirmed
- Purchase is confirmed by Immersve and E-Commerce merchant