Skip to main content

TwabDelegator

Git Source

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

NameTypeDescription
name_stringThe name for the staked vault token
symbol_stringThe symbol for the staked vault token
twabController_TwabControllerAddress of the TwabController contract
vault_IERC20Address 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

NameTypeDescription
_toaddressAddress to which the stake will be attributed
_amountuint256Amount 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

NameTypeDescription
_toaddressAddress of the recipient that will receive the Vault shares
_amountuint256Amount 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

NameTypeDescription
_delegatoraddressAddress of the delegator that will be able to handle the delegation
_slotuint256Slot of the delegation
_delegateeaddressAddress of the delegatee
_lockDurationuint96Duration of time for which the delegation is locked. Must be less than the max duration.

Returns

NameTypeDescription
<none>DelegationReturns 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

NameTypeDescription
_delegatoraddressAddress of the delegator
_slotuint256Slot of the delegation
_delegateeaddressAddress of the delegatee
_lockDurationuint96Duration of time during which the delegatee cannot be changed nor withdrawn

Returns

NameTypeDescription
<none>DelegationThe 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

NameTypeDescription
_delegatoraddressAddress of the delegator
_slotuint256Slot of the delegation
_amountuint256Amount of Vault shares to transfer

Returns

NameTypeDescription
<none>DelegationThe 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

NameTypeDescription
_delegatoraddressAddress of the delegator
_slotuint256Slot of the delegation
_amountuint256Amount of Vault shares to send to the delegation from the staked amount

Returns

NameTypeDescription
<none>DelegationThe 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

NameTypeDescription
_delegatoraddressAddress of the delegator
_slotuint256Slot of the delegation
_amountuint256Amount of Vault shares to withdraw

Returns

NameTypeDescription
<none>DelegationThe 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

NameTypeDescription
_slotuint256Slot of the delegation
_amountuint256Amount to withdraw
_toaddressAccount to transfer the withdrawn Vault shares to

Returns

NameTypeDescription
<none>DelegationThe 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

NameTypeDescription
_representativeaddressAddress of the representative
_setboolSet 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

NameTypeDescription
_delegatoraddressThe delegator
_representativeaddressThe representative to check for

Returns

NameTypeDescription
<none>boolTrue 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

NameTypeDescription
_databytes[]An array of encoded function calls. The calls must be abi-encoded calls to this contract.

Returns

NameTypeDescription
<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

NameTypeDescription
_amountuint256Amount of Vault shares to approve
_permitSignatureSignaturePermit signature
_databytes[]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

NameTypeDescription
_delegatoraddressThe delegator address
_slotuint256The delegation slot they are using

Returns

NameTypeDescription
delegationDelegationThe address that holds Vault shares for the delegation
delegateeaddressThe address that Vault shares are being delegated to
balanceuint256The balance of Vault shares in the delegation
lockUntiluint256The timestamp at which the delegation unlocks
wasCreatedboolWhether 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

NameTypeDescription
_delegatoraddressThe user who is delegating Vault shares
_slotuint256The delegation slot

Returns

NameTypeDescription
<none>addressThe 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

NameTypeDescription
<none>uint8ERC20 token decimals

twabController

Returns the TwabController address.

function twabController() external view returns (address);

Returns

NameTypeDescription
<none>addressTwabController address

vault

Returns the Vault address.

function vault() external view returns (address);

Returns

NameTypeDescription
<none>addressVault 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

NameTypeDescription
_delegatoraddressAddress of the delegator
_slotuint256Slot of the delegation

Returns

NameTypeDescription
<none>addressAddress 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

NameTypeDescription
_lockDurationuint96The duration of the lock

Returns

NameTypeDescription
<none>uint96The lock expiration timestamp

_setDelegateeCall

Delegates Vault shares from the _delegation contract to the _delegatee address.

function _setDelegateeCall(Delegation _delegation, address _delegatee) internal;

Parameters

NameTypeDescription
_delegationDelegationAddress of the delegation contract
_delegateeaddressAddress 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

NameTypeDescription
_delegationDelegationAddress of the delegation contract
_toaddressAddress of the recipient
_amountuint256Amount 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

NameTypeDescription
_delegationDelegationAddress of the delegation contract
_toaddressThe address that will be called
_databytesThe call data that will be executed

Returns

NameTypeDescription
<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

NameTypeDescription
_delegationDelegationAddress of the delegation contract
_toaddressAddress of the recipient
_amountuint256Amount 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

NameTypeDescription
_delegatoraddressAddress of the delegator

_requireDelegateeNotZeroAddress

Require to verify that _delegatee is not address zero.

function _requireDelegateeNotZeroAddress(address _delegatee) internal pure;

Parameters

NameTypeDescription
_delegateeaddressAddress of the delegatee

_requireAmountGtZero

Require to verify that _amount is greater than 0.

function _requireAmountGtZero(uint256 _amount) internal pure;

Parameters

NameTypeDescription
_amountuint256Amount to check

_requireRecipientNotZeroAddress

Require to verify that _to is not address zero.

function _requireRecipientNotZeroAddress(address _to) internal pure;

Parameters

NameTypeDescription
_toaddressAddress to check

_requireDelegationUnlocked

Require to verify if a _delegation is locked.

function _requireDelegationUnlocked(Delegation _delegation) internal view;

Parameters

NameTypeDescription
_delegationDelegationDelegation to check

_requireLockDuration

Require to verify that a _lockDuration does not exceed the maximum lock duration.

function _requireLockDuration(uint256 _lockDuration) internal pure;

Parameters

NameTypeDescription
_lockDurationuint256Lock duration to check

Events

TwabControllerSet

Emitted when TwabController associated with this contract has been set.

event TwabControllerSet(TwabController indexed twabController);

Parameters

NameTypeDescription
twabControllerTwabControllerAddress of the TwabController

VaultSet

Emitted when Vault associated with this contract has been set.

event VaultSet(IERC20 indexed vault);

Parameters

NameTypeDescription
vaultIERC20Address of the Vault

VaultSharesStaked

Emitted when Vault shares have been staked.

event VaultSharesStaked(address indexed delegator, uint256 amount);

Parameters

NameTypeDescription
delegatoraddressAddress of the delegator
amountuint256Amount of Vault shares shares staked

VaultSharesUnstaked

Emitted when Vault shares have been unstaked.

event VaultSharesUnstaked(address indexed delegator, address indexed recipient, uint256 amount);

Parameters

NameTypeDescription
delegatoraddressAddress of the delegator
recipientaddressAddress of the recipient that will receive the Vault shares
amountuint256Amount 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

NameTypeDescription
delegatoraddressDelegator of the delegation
slotuint256Slot of the delegation
lockUntiluint96Timestamp until which the delegation is locked
delegateeaddressAddress of the delegatee
delegationDelegationAddress of the delegation that was created
useraddressAddress 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

NameTypeDescription
delegatoraddressAddress of the delegator
slotuint256Slot of the delegation
delegateeaddressAddress of the delegatee
lockUntiluint96Timestamp until which the delegation is locked
useraddressAddress 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

NameTypeDescription
delegatoraddressAddress of the delegator
slotuint256Slot of the delegation
amountuint256Amount of Vault shares that were sent to the delegation
useraddressAddress 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

NameTypeDescription
delegatoraddressAddress of the delegator
slotuint256Slot of the delegation
amountuint256Amount of Vault shares that were sent to the delegation
useraddressAddress 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

NameTypeDescription
delegatoraddressAddress of the delegator
slotuint256Slot of the delegation
amountuint256Amount of Vault shares withdrawn
useraddressAddress 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

NameTypeDescription
delegatoraddressAddress of the delegator
slotuint256Slot of the delegation
amountuint256Amount of Vault shares withdrawn
toaddressRecipient address of withdrawn Vault shares

RepresentativeSet

Emitted when a representative is set.

event RepresentativeSet(address indexed delegator, address indexed representative, bool set);

Parameters

NameTypeDescription
delegatoraddressAddress of the delegator
representativeaddressAddress of the representative
setboolBoolean indicating if the representative was set or unset