Skip to content

Commit

Permalink
Merge pull request #572 from hats-finance/vault-deposit-from-airdrop
Browse files Browse the repository at this point in the history
Allow depositing into a vault on airdrop claim
  • Loading branch information
jellegerbrandy authored Jun 20, 2024
2 parents 4f252fa + 612a2c0 commit 443b17e
Show file tree
Hide file tree
Showing 25 changed files with 3,448 additions and 89 deletions.
2 changes: 1 addition & 1 deletion .solcover.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ module.exports = {
timeout: 100000,
},
configureYulOptimizer: true,
skipFiles: ['test/', 'mocks/', 'HATArbitrator.sol', 'HATKlerosV2Connector.sol'],
skipFiles: ['test/', 'mocks/', 'HATArbitrator.sol', 'HATKlerosV2Connector.sol', 'tge/HATAirdropFactory.sol'],
providerOptions: {
accounts: [
{
Expand Down
15 changes: 13 additions & 2 deletions contracts/tge/HATAirdrop.sol
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ contract HATAirdrop is IHATAirdrop, Initializable {
error InvalidMerkleProof();
error CannotRecoverBeforeDeadline();
error RedeemerMustBeBeneficiary();
error InvalidAmountToDeposit();

using SafeERC20Upgradeable for IERC20Upgradeable;

Expand Down Expand Up @@ -71,7 +72,7 @@ contract HATAirdrop is IHATAirdrop, Initializable {
emit MerkleTreeSet(_merkleTreeIPFSRef, _root, _startTime, _deadline);
}

function redeem(address _account, uint256 _amount, bytes32[] calldata _proof) external {
function redeem(address _account, uint256 _amount, bytes32[] calldata _proof, IHATVault _depositIntoVault, uint256 _amountToDeposit, uint256 _minShares) external {
if (msg.sender != _account && msg.sender != factory) {
revert RedeemerMustBeBeneficiary();
}
Expand Down Expand Up @@ -102,7 +103,17 @@ contract HATAirdrop is IHATAirdrop, Initializable {
);
token.safeTransferFrom(factory, _tokenLock, _amount);
} else {
token.safeTransferFrom(factory, _account, _amount);
if (address(_depositIntoVault) != address(0)) {
if (_amountToDeposit > _amount || _amountToDeposit == 0) {
revert InvalidAmountToDeposit();
}
token.safeApprove(address(_depositIntoVault), _amountToDeposit);
token.safeTransferFrom(factory, address(this), _amountToDeposit);
_depositIntoVault.deposit(_amountToDeposit, _account, _minShares);
token.safeTransferFrom(factory, _account, _amount - _amountToDeposit);
} else {
token.safeTransferFrom(factory, _account, _amount);
}
}

emit TokensRedeemed(_account, _tokenLock, _amount);
Expand Down
24 changes: 20 additions & 4 deletions contracts/tge/HATAirdropFactory.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "./interfaces/IHATAirdrop.sol";
import "../interfaces/IHATToken.sol";
import "../interfaces/IHATVault.sol";

contract HATAirdropFactory is Ownable {
error RedeemDataArraysLengthMismatch();
Expand All @@ -33,8 +34,20 @@ contract HATAirdropFactory is Ownable {
emit TokensWithdrawn(owner, _amount);
}

function redeemMultipleAirdrops(IHATAirdrop[] calldata _airdrops, uint256[] calldata _amounts, bytes32[][] calldata _proofs) public {
if (_airdrops.length != _amounts.length || _airdrops.length != _proofs.length) {
function redeemMultipleAirdrops(
IHATAirdrop[] calldata _airdrops,
uint256[] calldata _amounts,
bytes32[][] calldata _proofs,
IHATVault[] calldata _depositIntoVaults,
uint256[] calldata _amountsToDeposit,
uint256[] calldata _minShares
) public {
if (
_airdrops.length != _amounts.length ||
_airdrops.length != _proofs.length ||
_airdrops.length != _depositIntoVaults.length ||
_airdrops.length != _amountsToDeposit.length ||
_airdrops.length != _minShares.length) {
revert RedeemDataArraysLengthMismatch();
}

Expand All @@ -44,7 +57,7 @@ contract HATAirdropFactory is Ownable {
revert ContractIsNotHATAirdrop();
}

_airdrops[i].redeem(caller, _amounts[i], _proofs[i]);
_airdrops[i].redeem(caller, _amounts[i], _proofs[i], _depositIntoVaults[i], _amountsToDeposit[i], _minShares[i]);

unchecked {
++i;
Expand All @@ -56,14 +69,17 @@ contract HATAirdropFactory is Ownable {
IHATAirdrop[] calldata _airdrops,
uint256[] calldata _amounts,
bytes32[][] calldata _proofs,
IHATVault[] calldata _depositIntoVaults,
uint256[] calldata _amountsToDeposit,
uint256[] calldata _minShares,
address _delegatee,
uint256 _nonce,
uint256 _expiry,
uint8 _v,
bytes32 _r,
bytes32 _s
) external {
redeemMultipleAirdrops(_airdrops, _amounts, _proofs);
redeemMultipleAirdrops(_airdrops, _amounts, _proofs, _depositIntoVaults, _amountsToDeposit, _minShares);

HAT.delegateBySig(_delegatee, _nonce, _expiry, _v, _r, _s);
}
Expand Down
4 changes: 3 additions & 1 deletion contracts/tge/interfaces/IHATAirdrop.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@

pragma solidity 0.8.16;

import "../../interfaces/IHATVault.sol";


interface IHATAirdrop {
function redeem(address _account, uint256 _amount, bytes32[] calldata _proof) external;
function redeem(address _account, uint256 _amount, bytes32[] calldata _proof, IHATVault _depositIntoVault, uint256 _amountToDeposit, uint256 _minShares) external;
}
Loading

0 comments on commit 443b17e

Please sign in to comment.