TwabDelegator
Inherits: ERC20, LowLevelDelegator, PermitAndMulticall
This contract allows accounts to easily delegate a portion of their Vault shares to multiple delegatees. The delegatees chance of winning prizes is increased by the delegated amount. If a delegator doesn't want to actively manage the delegations, then they can stake on the contract and appoint representatives.
State Variables
_vault
Vault to which this contract is tied to.
IERC20 private immutable _vault;
_twabController
TwabController to which this contract is tied to.
TwabController private immutable _twabController;
MAX_LOCK
Max lock time during which a delegation cannot be updated.
uint256 public constant MAX_LOCK = 180 days;
representatives
Representative elected by the delegator to handle delegation.
Representative can only handle delegation and cannot withdraw Vault shares to their wallet.
delegator => representative => bool allowing representative to represent the delegator
mapping(address => mapping(address => bool)) internal representatives;
Functions
constructor
Creates a new TWAB Delegator that is bound to the given vault contract.
constructor(string memory name_, string memory symbol_, TwabController twabController_, IERC20 vault_)
    LowLevelDelegator()
    ERC20(name_, symbol_);
Parameters
| Name | Type | Description | 
|---|---|---|
name_ | string | The name for the staked vault token | 
symbol_ | string | The symbol for the staked vault token | 
twabController_ | TwabController | Address of the TwabController contract | 
vault_ | IERC20 | Address of the Vault contract | 
stake
Stake _amount of Vault shares in this contract.
Vault Shares can be staked on behalf of a _to user.
function stake(address _to, uint256 _amount) external;
Parameters
| Name | Type | Description | 
|---|---|---|
_to | address | Address to which the stake will be attributed | 
_amount | uint256 | Amount of Vault shares to stake | 
unstake
Unstake _amount of Vault shares from this contract. Transfers Vault shares to the passed _to address.
If delegator has delegated his whole stake, he will first have to withdraw from a delegation to be able to unstake.
function unstake(address _to, uint256 _amount) external;
Parameters
| Name | Type | Description | 
|---|---|---|
_to | address | Address of the recipient that will receive the Vault shares | 
_amount | uint256 | Amount of Vault shares to unstake | 
createDelegation
Creates a new delegation. This will create a new Delegation contract for the given slot and have it delegate its Vault shares to the given delegatee. If a non-zero lock duration is passed, then the delegatee cannot be changed, nor funding withdrawn, until the lock has expired.
The _delegator and _slot params are used to compute the salt of the delegation
function createDelegation(address _delegator, uint256 _slot, address _delegatee, uint96 _lockDuration)
    external
    returns (Delegation);
Parameters
| Name | Type | Description | 
|---|---|---|
_delegator | address | Address of the delegator that will be able to handle the delegation | 
_slot | uint256 | Slot of the delegation | 
_delegatee | address | Address of the delegatee | 
_lockDuration | uint96 | Duration of time for which the delegation is locked. Must be less than the max duration. | 
Returns
| Name | Type | Description | 
|---|---|---|
<none> | Delegation | Returns the address of the Delegation contract that will hold the Vault shares | 
updateDelegatee
Updates the delegatee and lock duration for a delegation slot.
Only callable by the _delegator or their representative.
Will revert if delegation is still locked.
function updateDelegatee(address _delegator, uint256 _slot, address _delegatee, uint96 _lockDuration)
    external
    returns (Delegation);
Parameters
| Name | Type | Description | 
|---|---|---|
_delegator | address | Address of the delegator | 
_slot | uint256 | Slot of the delegation | 
_delegatee | address | Address of the delegatee | 
_lockDuration | uint96 | Duration of time during which the delegatee cannot be changed nor withdrawn | 
Returns
| Name | Type | Description | 
|---|---|---|
<none> | Delegation | The address of the Delegation | 
fundDelegation
Fund a delegation by transferring Vault shares from the caller to the delegation.
Callable by anyone.
Will revert if delegation does not exist.
function fundDelegation(address _delegator, uint256 _slot, uint256 _amount) external returns (Delegation);
Parameters
| Name | Type | Description | 
|---|---|---|
_delegator | address | Address of the delegator | 
_slot | uint256 | Slot of the delegation | 
_amount | uint256 | Amount of Vault shares to transfer | 
Returns
| Name | Type | Description | 
|---|---|---|
<none> | Delegation | The address of the Delegation | 
fundDelegationFromStake
Fund a delegation using the _delegator stake.
Callable only by the _delegator or a representative.
Will revert if delegation does not exist.
Will revert if _amount is greater than the staked amount.
function fundDelegationFromStake(address _delegator, uint256 _slot, uint256 _amount) external returns (Delegation);
Parameters
| Name | Type | Description | 
|---|---|---|
_delegator | address | Address of the delegator | 
_slot | uint256 | Slot of the delegation | 
_amount | uint256 | Amount of Vault shares to send to the delegation from the staked amount | 
Returns
| Name | Type | Description | 
|---|---|---|
<none> | Delegation | The address of the Delegation | 
withdrawDelegationToStake
Withdraw Vault shares from a delegation. The Vault shares will be held by this contract and the delegator's stake will increase.
Only callable by the _delegator or a representative.
Will send the Vault shares to this contract and increase the _delegator staked amount.
Will revert if delegation is still locked.
function withdrawDelegationToStake(address _delegator, uint256 _slot, uint256 _amount) external returns (Delegation);
Parameters
| Name | Type | Description | 
|---|---|---|
_delegator | address | Address of the delegator | 
_slot | uint256 | Slot of the delegation | 
_amount | uint256 | Amount of Vault shares to withdraw | 
Returns
| Name | Type | Description | 
|---|---|---|
<none> | Delegation | The address of the Delegation | 
transferDelegationTo
Withdraw an _amount of Vault shares from a delegation. The delegator is assumed to be the caller.
Vault Shares are sent directly to the passed _to address.
Will revert if delegation is still locked.
function transferDelegationTo(uint256 _slot, uint256 _amount, address _to) external returns (Delegation);
Parameters
| Name | Type | Description | 
|---|---|---|
_slot | uint256 | Slot of the delegation | 
_amount | uint256 | Amount to withdraw | 
_to | address | Account to transfer the withdrawn Vault shares to | 
Returns
| Name | Type | Description | 
|---|---|---|
<none> | Delegation | The address of the Delegation | 
setRepresentative
Allow an account to set or unset a _representative to handle delegation.
If _set is true, _representative will be set as representative of msg.sender.
If _set is false, _representative will be unset as representative of msg.sender.
function setRepresentative(address _representative, bool _set) external;
Parameters
| Name | Type | Description | 
|---|---|---|
_representative | address | Address of the representative | 
_set | bool | Set or unset the representative | 
isRepresentativeOf
Returns whether or not the given rep is a representative of the delegator.
function isRepresentativeOf(address _delegator, address _representative) external view returns (bool);
Parameters
| Name | Type | Description | 
|---|---|---|
_delegator | address | The delegator | 
_representative | address | The representative to check for | 
Returns
| Name | Type | Description | 
|---|---|---|
<none> | bool | True if the rep is a rep, false otherwise | 
multicall
Allows a user to call multiple functions on the same contract. Useful for EOA who wants to batch transactions.
function multicall(bytes[] calldata _data) external returns (bytes[] memory);
Parameters
| Name | Type | Description | 
|---|---|---|
_data | bytes[] | An array of encoded function calls. The calls must be abi-encoded calls to this contract. | 
Returns
| Name | Type | Description | 
|---|---|---|
<none> | bytes[] | The results from each function call | 
permitAndMulticall
Alow a user to approve Vault shares and run various calls in one transaction.
function permitAndMulticall(uint256 _amount, Signature calldata _permitSignature, bytes[] calldata _data) external;
Parameters
| Name | Type | Description | 
|---|---|---|
_amount | uint256 | Amount of Vault shares to approve | 
_permitSignature | Signature | Permit signature | 
_data | bytes[] | Datas to call with functionDelegateCall | 
getDelegation
Allows the caller to easily get the details for a delegation.
function getDelegation(address _delegator, uint256 _slot)
    external
    view
    returns (Delegation delegation, address delegatee, uint256 balance, uint256 lockUntil, bool wasCreated);
Parameters
| Name | Type | Description | 
|---|---|---|
_delegator | address | The delegator address | 
_slot | uint256 | The delegation slot they are using | 
Returns
| Name | Type | Description | 
|---|---|---|
delegation | Delegation | The address that holds Vault shares for the delegation | 
delegatee | address | The address that Vault shares are being delegated to | 
balance | uint256 | The balance of Vault shares in the delegation | 
lockUntil | uint256 | The timestamp at which the delegation unlocks | 
wasCreated | bool | Whether or not the delegation has been created | 
computeDelegationAddress
Computes the address of the delegation for the delegator + slot combination.
function computeDelegationAddress(address _delegator, uint256 _slot) external view returns (address);
Parameters
| Name | Type | Description | 
|---|---|---|
_delegator | address | The user who is delegating Vault shares | 
_slot | uint256 | The delegation slot | 
Returns
| Name | Type | Description | 
|---|---|---|
<none> | address | The address of the delegation. This is the address that holds the balance of Vault shares. | 
decimals
Returns the ERC20 token decimals.
This value is equal to the decimals of the Vault shares being delegated.
function decimals() public view virtual override returns (uint8);
Returns
| Name | Type | Description | 
|---|---|---|
<none> | uint8 | ERC20 token decimals | 
twabController
Returns the TwabController address.
function twabController() external view returns (address);
Returns
| Name | Type | Description | 
|---|---|---|
<none> | address | TwabController address | 
vault
Returns the Vault address.
function vault() external view returns (address);
Returns
| Name | Type | Description | 
|---|---|---|
<none> | address | Vault address | 
_computeAddress
Computes the address of a delegation contract using the delegator and slot as a salt. The contract is a clone, also known as minimal proxy contract.
function _computeAddress(address _delegator, uint256 _slot) internal view returns (address);
Parameters
| Name | Type | Description | 
|---|---|---|
_delegator | address | Address of the delegator | 
_slot | uint256 | Slot of the delegation | 
Returns
| Name | Type | Description | 
|---|---|---|
<none> | address | Address at which the delegation contract will be deployed | 
_computeLockUntil
Computes the timestamp at which the delegation unlocks, after which the delegatee can be changed and Vault shares withdrawn.
function _computeLockUntil(uint96 _lockDuration) internal view returns (uint96);
Parameters
| Name | Type | Description | 
|---|---|---|
_lockDuration | uint96 | The duration of the lock | 
Returns
| Name | Type | Description | 
|---|---|---|
<none> | uint96 | The lock expiration timestamp | 
_setDelegateeCall
Delegates Vault shares from the _delegation contract to the _delegatee address.
function _setDelegateeCall(Delegation _delegation, address _delegatee) internal;
Parameters
| Name | Type | Description | 
|---|---|---|
_delegation | Delegation | Address of the delegation contract | 
_delegatee | address | Address of the delegatee | 
_transferCall
Tranfers Vault shares from the Delegation contract to the _to address.
function _transferCall(Delegation _delegation, address _to, uint256 _amount) internal;
Parameters
| Name | Type | Description | 
|---|---|---|
_delegation | Delegation | Address of the delegation contract | 
_to | address | Address of the recipient | 
_amount | uint256 | Amount of Vault shares to transfer | 
_executeCall
Execute a function call on the delegation contract.
function _executeCall(Delegation _delegation, address _to, bytes memory _data) internal returns (bytes[] memory);
Parameters
| Name | Type | Description | 
|---|---|---|
_delegation | Delegation | Address of the delegation contract | 
_to | address | The address that will be called | 
_data | bytes | The call data that will be executed | 
Returns
| Name | Type | Description | 
|---|---|---|
<none> | bytes[] | The return datas from the calls | 
_transfer
Transfers Vault shares from a delegation contract to _to.
function _transfer(Delegation _delegation, address _to, uint256 _amount) internal;
Parameters
| Name | Type | Description | 
|---|---|---|
_delegation | Delegation | Address of the delegation contract | 
_to | address | Address of the recipient | 
_amount | uint256 | Amount of Vault shares to transfer | 
_requireDelegatorOrRepresentative
Require to only allow the delegator or representative to call a function.
function _requireDelegatorOrRepresentative(address _delegator) internal view;
Parameters
| Name | Type | Description | 
|---|---|---|
_delegator | address | Address of the delegator | 
_requireDelegateeNotZeroAddress
Require to verify that _delegatee is not address zero.
function _requireDelegateeNotZeroAddress(address _delegatee) internal pure;
Parameters
| Name | Type | Description | 
|---|---|---|
_delegatee | address | Address of the delegatee | 
_requireAmountGtZero
Require to verify that _amount is greater than 0.
function _requireAmountGtZero(uint256 _amount) internal pure;
Parameters
| Name | Type | Description | 
|---|---|---|
_amount | uint256 | Amount to check | 
_requireRecipientNotZeroAddress
Require to verify that _to is not address zero.
function _requireRecipientNotZeroAddress(address _to) internal pure;
Parameters
| Name | Type | Description | 
|---|---|---|
_to | address | Address to check | 
_requireDelegationUnlocked
Require to verify if a _delegation is locked.
function _requireDelegationUnlocked(Delegation _delegation) internal view;
Parameters
| Name | Type | Description | 
|---|---|---|
_delegation | Delegation | Delegation to check | 
_requireLockDuration
Require to verify that a _lockDuration does not exceed the maximum lock duration.
function _requireLockDuration(uint256 _lockDuration) internal pure;
Parameters
| Name | Type | Description | 
|---|---|---|
_lockDuration | uint256 | Lock duration to check | 
Events
TwabControllerSet
Emitted when TwabController associated with this contract has been set.
event TwabControllerSet(TwabController indexed twabController);
Parameters
| Name | Type | Description | 
|---|---|---|
twabController | TwabController | Address of the TwabController | 
VaultSet
Emitted when Vault associated with this contract has been set.
event VaultSet(IERC20 indexed vault);
Parameters
| Name | Type | Description | 
|---|---|---|
vault | IERC20 | Address of the Vault | 
VaultSharesStaked
Emitted when Vault shares have been staked.
event VaultSharesStaked(address indexed delegator, uint256 amount);
Parameters
| Name | Type | Description | 
|---|---|---|
delegator | address | Address of the delegator | 
amount | uint256 | Amount of Vault shares shares staked | 
VaultSharesUnstaked
Emitted when Vault shares have been unstaked.
event VaultSharesUnstaked(address indexed delegator, address indexed recipient, uint256 amount);
Parameters
| Name | Type | Description | 
|---|---|---|
delegator | address | Address of the delegator | 
recipient | address | Address of the recipient that will receive the Vault shares | 
amount | uint256 | Amount of Vault shares unstaked | 
DelegationCreated
Emitted when a new delegation is created.
event DelegationCreated(
    address indexed delegator,
    uint256 indexed slot,
    uint96 lockUntil,
    address indexed delegatee,
    Delegation delegation,
    address user
);
Parameters
| Name | Type | Description | 
|---|---|---|
delegator | address | Delegator of the delegation | 
slot | uint256 | Slot of the delegation | 
lockUntil | uint96 | Timestamp until which the delegation is locked | 
delegatee | address | Address of the delegatee | 
delegation | Delegation | Address of the delegation that was created | 
user | address | Address of the user who created the delegation | 
DelegateeUpdated
Emitted when a delegatee is updated.
event DelegateeUpdated(
    address indexed delegator, uint256 indexed slot, address indexed delegatee, uint96 lockUntil, address user
);
Parameters
| Name | Type | Description | 
|---|---|---|
delegator | address | Address of the delegator | 
slot | uint256 | Slot of the delegation | 
delegatee | address | Address of the delegatee | 
lockUntil | uint96 | Timestamp until which the delegation is locked | 
user | address | Address of the user who updated the delegatee | 
DelegationFunded
Emitted when a delegation is funded.
event DelegationFunded(address indexed delegator, uint256 indexed slot, uint256 amount, address indexed user);
Parameters
| Name | Type | Description | 
|---|---|---|
delegator | address | Address of the delegator | 
slot | uint256 | Slot of the delegation | 
amount | uint256 | Amount of Vault shares that were sent to the delegation | 
user | address | Address of the user who funded the delegation | 
DelegationFundedFromStake
Emitted when a delegation is funded from the staked amount.
event DelegationFundedFromStake(address indexed delegator, uint256 indexed slot, uint256 amount, address indexed user);
Parameters
| Name | Type | Description | 
|---|---|---|
delegator | address | Address of the delegator | 
slot | uint256 | Slot of the delegation | 
amount | uint256 | Amount of Vault shares that were sent to the delegation | 
user | address | Address of the user who pulled funds from the delegator stake to the delegation | 
WithdrewDelegationToStake
Emitted when an amount of Vault shares has been withdrawn from a delegation.
The Vault shares are held by this contract and the delegator stake is increased.
event WithdrewDelegationToStake(address indexed delegator, uint256 indexed slot, uint256 amount, address indexed user);
Parameters
| Name | Type | Description | 
|---|---|---|
delegator | address | Address of the delegator | 
slot | uint256 | Slot of the delegation | 
amount | uint256 | Amount of Vault shares withdrawn | 
user | address | Address of the user who withdrew the Vault shares | 
TransferredDelegation
Emitted when a delegator withdraws an amount of Vault shares from a delegation to a specified wallet.
event TransferredDelegation(address indexed delegator, uint256 indexed slot, uint256 amount, address indexed to);
Parameters
| Name | Type | Description | 
|---|---|---|
delegator | address | Address of the delegator | 
slot | uint256 | Slot of the delegation | 
amount | uint256 | Amount of Vault shares withdrawn | 
to | address | Recipient address of withdrawn Vault shares | 
RepresentativeSet
Emitted when a representative is set.
event RepresentativeSet(address indexed delegator, address indexed representative, bool set);
Parameters
| Name | Type | Description | 
|---|---|---|
delegator | address | Address of the delegator | 
representative | address | Address of the representative | 
set | bool | Boolean indicating if the representative was set or unset |