Skip to main content

JBBuybackDelegate

Git Source

Inherits: Ownable, ERC165, JBDelegateMetadataHelper, IJBFundingCycleDataSource3_1_1, IJBPayDelegate3_1_1, IUniswapV3SwapCallback

Datasource and delegate allowing pay beneficiary to get the highest amount of project tokens between minting using the project weigh and swapping in a given Uniswap V3 pool.

This only supports ETH terminal. The pool is fixed, if a new pool offers deeper liquidity, this delegate needs to be redeployed.

State Variables

PROJECT_TOKEN_IS_TOKEN0

Address project token < address terminal token ?

bool immutable PROJECT_TOKEN_IS_TOKEN0;

SLIPPAGE_DENOMINATOR

The unit of the max slippage (expressed in 1/10000th)

uint256 constant SLIPPAGE_DENOMINATOR = 10000;

PROJECT_TOKEN

The project token address

In this context, this is the tokenOut

IERC20 public immutable PROJECT_TOKEN;

POOL

The uniswap pool corresponding to the project token-other token market (this should be carefully chosen liquidity wise)

IUniswapV3Pool public immutable POOL;

DIRECTORY

The JB Directory

IJBDirectory public immutable DIRECTORY;

CONTROLLER

The project controller

IJBController3_1 public immutable CONTROLLER;

WETH

The WETH contract

IWETH9 public immutable WETH;

delegateId

The 4bytes ID of this delegate, used for metadata parsing

bytes4 public immutable delegateId;

secondsAgo

uint32 public secondsAgo;

twapDelta

uint256 public twapDelta;

sweepBalanceOf

mapping(address => uint256) public sweepBalanceOf;

sweepBalance

uint256 public sweepBalance;

Functions

constructor

No other logic besides initializing the immutables

constructor(
IERC20 _projectToken,
IWETH9 _weth,
address _factory,
uint24 _fee,
uint32 _secondsAgo,
uint256 _twapDelta,
IJBDirectory _directory,
IJBController3_1 _controller,
bytes4 _delegateId
);

payParams

The datasource implementation

function payParams(JBPayParamsData calldata _data)
external
view
override
returns (uint256 weight, string memory memo, JBPayDelegateAllocation3_1_1[] memory delegateAllocations);

Parameters

NameTypeDescription
_dataJBPayParamsDatathe data passed to the data source in terminal.pay(..). _data.metadata need to have the Uniswap quote this quote should be set as 0 if the user wants to use the vanilla minting path

Returns

NameTypeDescription
weightuint256the weight to use (the one passed if not max reserved rate, 0 if swapping or the one corresponding to the reserved token to mint if minting)
memostringthe original memo passed
delegateAllocationsJBPayDelegateAllocation3_1_1[]The amount to send to delegates instead of adding to the local balance.

didPay

Delegate to either swap to the beneficiary or mint to the beneficiary

This delegate is called only if the quote for the swap is bigger than the lowest received when minting. If the swap reverts (slippage, liquidity, etc), the delegate will then mint the same amount of token as if the delegate was not used. If the beneficiary requests non claimed token, the swap is not used (as it is, per definition, claimed token)

function didPay(JBDidPayData3_1_1 calldata _data) external payable override;

Parameters

NameTypeDescription
_dataJBDidPayData3_1_1the delegate data passed by the terminal

uniswapV3SwapCallback

The Uniswap V3 pool callback (where token transfer should happens)

Slippage controle is achieved here

function uniswapV3SwapCallback(int256 amount0Delta, int256 amount1Delta, bytes calldata data) external override;

redeemParams

Generic redeem params, for interface completion

This is a passthrough of the redemption parameters

function redeemParams(JBRedeemParamsData calldata _data)
external
pure
override
returns (
uint256 reclaimAmount,
string memory memo,
JBRedemptionDelegateAllocation3_1_1[] memory delegateAllocations
);

Parameters

NameTypeDescription
_dataJBRedeemParamsDatathe redeem data passed by the terminal

increaseSecondsAgo

Increase the period over which the twap is computed

function increaseSecondsAgo(uint32 _newSecondsAgo) external onlyOwner;

Parameters

NameTypeDescription
_newSecondsAgouint32the new period

setTwapDelta

Set the maximum deviation allowed between amount received and twap

function setTwapDelta(uint256 _newDelta) external onlyOwner;

Parameters

NameTypeDescription
_newDeltauint256the new delta, in 10_000th

sweep

Sweep the eth left-over in this contract

function sweep(address _beneficiary) external;

_getQuote

Get a quote based on twap over a secondsAgo period, taking into account a twapDelta max deviation

function _getQuote(uint256 _amountIn) internal view returns (uint256 _amountOut);

Parameters

NameTypeDescription
_amountInuint256the amount to swap

Returns

NameTypeDescription
_amountOutuint256the minimum amount received according to the twap

_swap

Swap the terminal token to receive the project token _beforeTransfer

  1. This delegate first receive the whole amount of project token,
  2. then send the non-reserved token to the beneficiary,
  3. then burn the rest of this delegate balance (ie the amount of reserved token),
  4. then mint the same amount as received (this will add the reserved token, following the fc rate)
  5. then burn the difference (ie this delegate balance)

-> End result is having the correct balances (beneficiary and reserve), according to the reserve rate

function _swap(JBDidPayData3_1_1 calldata _data, uint256 _minimumReceivedFromSwap)
internal
returns (uint256 _amountReceived);

Parameters

NameTypeDescription
_dataJBDidPayData3_1_1the didPayData passed by the terminal
_minimumReceivedFromSwapuint256the minimum amount received, to prevent slippage

_mint

Mint the token out, sending back the token in the terminal

function _mint(JBDidPayData3_1_1 calldata _data, uint256 _amount) internal;

Parameters

NameTypeDescription
_dataJBDidPayData3_1_1the didPayData passed by the terminal
_amountuint256the amount of token out to mint

supportsInterface

function supportsInterface(bytes4 _interfaceId) public view override(ERC165, IERC165) returns (bool);

Events

BuybackDelegate_Swap

event BuybackDelegate_Swap(uint256 projectId, uint256 amountEth, uint256 amountOut);

BuybackDelegate_Mint

event BuybackDelegate_Mint(uint256 projectId);

BuybackDelegate_SecondsAgoIncrease

event BuybackDelegate_SecondsAgoIncrease(uint256 oldSecondsAgo, uint256 newSecondsAgo);

BuybackDelegate_TwapDeltaChanged

event BuybackDelegate_TwapDeltaChanged(uint256 oldTwapDelta, uint256 newTwapDelta);

BuybackDelegate_PendingSweep

event BuybackDelegate_PendingSweep(address indexed beneficiary, uint256 amount);

Errors

JuiceBuyback_Unauthorized

error JuiceBuyback_Unauthorized();

JuiceBuyback_MaximumSlippage

error JuiceBuyback_MaximumSlippage();

JuiceBuyback_NewSecondsAgoTooLow

error JuiceBuyback_NewSecondsAgoTooLow();

JuiceBuyback_TransferFailed

error JuiceBuyback_TransferFailed();