Wallet
Git Source (opens in a new tab)
Inherits: Ownable, Coordinated
Payments wallet that allows: (1) managing ETH & ERC20 token balances, (2) allowing consumers to spend balance, (3) allowing coordinator to manage balance
Implements Ownable
to setup an update-able Wallet
owner
Implements Coordinated
to restrict payment-handling functions to being called from coordinator
It is known that a frontrunning exploit exists (similar to the approve
ERC20 vulnerability), where a consumer can request compute, and frontrun with a withdraw before the compute
is delivered forcing unpaid compute execution (for results that can be copied and used). Solving for this vulnerability (for example, with Chainlink subscriptions' always-preserved balances) is
ignored, instead delegating to (1) reputation systems at the node-level for ease-of-use.
State Variables
lockedBalance
token address => locked balance in escrow
address(0) represents ETH
mapping(address => uint256) private lockedBalance;
allowance
consumer => token address => spend limit
Exposes public getter to enable checking allowance
mapping(address => mapping(address => uint256)) public allowance;
Functions
constructor
Initializes new Wallet
constructor(Registry registry, address initialOwner) Coordinated(registry);
Parameters
Name | Type | Description |
---|---|---|
registry | Registry | registry contract |
initialOwner | address | intial wallet owner |
_getUnlockedBalance
Returns balance of token
that is not currently locked in escrow
function _getUnlockedBalance(address token) internal view returns (uint256);
Parameters
Name | Type | Description |
---|---|---|
token | address | token address (ERC20 contract address or address(0) for ETH) |
Returns
Name | Type | Description |
---|---|---|
<none> | uint256 | unlocked token balance |
_transferToken
Transfers amount
token
from address(this)
to to
function _transferToken(address token, address to, uint256 amount) internal;
Parameters
Name | Type | Description |
---|---|---|
token | address | token to transfer (ERC20 contract address or address(0) for ETH) |
to | address | address to transfer to |
amount | uint256 | amount of token to transfer |
withdraw
Allows owner
to withdraw amount
token
(s)
Can only withdraw tokens not locked in escrow
function withdraw(address token, uint256 amount) external onlyOwner;
Parameters
Name | Type | Description |
---|---|---|
token | address | token address |
amount | uint256 | amount of tokens to withdraw from Wallet |
approve
Allows owner
to approve spender
as a consumer that can spend amount
token
(s) from Wallet
We purposefully ignore the approve
frontrunning vulnerability as it is rarely applied in practice
function approve(address spender, address token, uint256 amount) external onlyOwner;
Parameters
Name | Type | Description |
---|---|---|
spender | address | consumer address to approve |
token | address | token address to approve spend for |
amount | uint256 | approval amount |
cTransfer
Allows coordinator to transfer amount
tokens
to to
on behalf of spender
function cTransfer(address spender, address token, address to, uint256 amount) external onlyCoordinator;
Parameters
Name | Type | Description |
---|---|---|
spender | address | on-behalf of whom to transfer tokens |
token | address | token to transfer (ERC20 contract address or address(0) for ETH) |
to | address | address to transfer to |
amount | uint256 | amount of token to transfer |
cLock
Allows coordinator to lock amount
token
(s) in escrow on behalf of spender
function cLock(address spender, address token, uint256 amount) external onlyCoordinator;
Parameters
Name | Type | Description |
---|---|---|
spender | address | on-behalf of whom tokens are locked |
token | address | token to lock |
amount | uint256 | amount to lock |
cUnlock
Allows coordinator to unlock amount
token
(s) from escrow on behalf of spender
function cUnlock(address spender, address token, uint256 amount) external onlyCoordinator;
Parameters
Name | Type | Description |
---|---|---|
spender | address | on-behalf of whom tokens are unlocked |
token | address | token to unlock |
amount | uint256 | amount to unlock |
receive
Allow ETH deposits to Wallet
receive() external payable;
Errors
TransferFailed
Thrown by _transferToken
if token transfer fails
4-byte signature: 0x90b8ec18
error TransferFailed();
InsufficientFunds
Thrown if attempting to transfer or lock tokens in quantity greater than possible
Thrown by withdraw()
if attempting to withdraw amount > unlockedBalance
Thrown by cLock()
if attempting to escrow amount > unlockedBalance
Thrown by cUnlock()
if attempting to unlock amount > lockedBalance
4-byte signature: 0x356680b7
error InsufficientFunds();
InsufficientAllowance
Thrown if attempting to transfer or lock tokens in quantity greater than allowed to a spender
Thrown by cTranasfer()
if attempting to transfer amount
> allowed
Thrown by cLock()
if attempting to lcok amount
> allowed
4-byte signature: 0x13be252b
error InsufficientAllowance();