Skip to content

Commit

Permalink
build: pre and post hooks (#34)
Browse files Browse the repository at this point in the history
* build: pre and post hooks

* fix: hooks

* fix: safe approve

* chore: organize

* fix: order
  • Loading branch information
Schlagonia authored Feb 6, 2024
1 parent 82c2751 commit ae73e78
Show file tree
Hide file tree
Showing 7 changed files with 508 additions and 7 deletions.
File renamed without changes.
File renamed without changes.
148 changes: 148 additions & 0 deletions src/Bases/Hooks/BaseHooks.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
// SPDX-License-Identifier: AGPL-3.0
pragma solidity 0.8.18;

import {Hooks} from "./Hooks.sol";
import {BaseHealthCheck, ERC20} from "../HealthCheck/BaseHealthCheck.sol";

/**
* @title Base Hooks
* @author Yearn.finance
* @notice This contract can be inherited by any Yearn
* strategy wishing to implement pre or post deposit, withdraw
* or transfer hooks in their strategy.
*/
abstract contract BaseHooks is BaseHealthCheck, Hooks {
constructor(
address _asset,
string memory _name
) BaseHealthCheck(_asset, _name) {}

Check warning on line 18 in src/Bases/Hooks/BaseHooks.sol

View workflow job for this annotation

GitHub Actions / solidity

Code contains empty blocks

// Deposit
function deposit(
uint256 assets,
address receiver
) external virtual returns (uint256 shares) {
_preDepositHook(assets, shares, receiver);
shares = abi.decode(
_delegateCall(
abi.encodeCall(TokenizedStrategy.deposit, (assets, receiver))
),
(uint256)
);
_postDepositHook(assets, shares, receiver);
}

// Mint
function mint(
uint256 shares,
address receiver
) external virtual returns (uint256 assets) {
_preDepositHook(assets, shares, receiver);
assets = abi.decode(
_delegateCall(
abi.encodeCall(TokenizedStrategy.mint, (shares, receiver))
),
(uint256)
);
_postDepositHook(assets, shares, receiver);
}

// Withdraw
function withdraw(
uint256 assets,
address receiver,
address owner
) external virtual returns (uint256 shares) {
return withdraw(assets, receiver, owner, 0);
}

function withdraw(
uint256 assets,
address receiver,
address owner,
uint256 maxLoss
) public virtual returns (uint256 shares) {
_preWithdrawHook(assets, shares, receiver, owner, maxLoss);
shares = abi.decode(
_delegateCall(
// Have to use encodeWithSignature due to overloading parameters.
abi.encodeWithSignature(
"withdraw(uint256,address,address,uint256)",
assets,
receiver,
owner,
maxLoss
)
),
(uint256)
);
_postWithdrawHook(assets, shares, receiver, owner, maxLoss);
}

// Redeem
function redeem(
uint256 shares,
address receiver,
address owner
) external virtual returns (uint256) {
// We default to not limiting a potential loss.
return redeem(shares, receiver, owner, MAX_BPS);
}

function redeem(
uint256 shares,
address receiver,
address owner,
uint256 maxLoss
) public returns (uint256 assets) {
_preWithdrawHook(assets, shares, receiver, owner, maxLoss);
assets = abi.decode(
_delegateCall(
// Have to use encodeWithSignature due to overloading parameters.
abi.encodeWithSignature(
"redeem(uint256,address,address,uint256)",
shares,
receiver,
owner,
maxLoss
)
),
(uint256)
);
_postWithdrawHook(assets, shares, receiver, owner, maxLoss);
}

// Transfer
function transferFrom(
address from,
address to,
uint256 amount
) public virtual returns (bool success) {
_preTransferHook(from, to, amount);
success = abi.decode(
_delegateCall(
abi.encodeCall(
TokenizedStrategy.transferFrom,
(from, to, amount)
)
),
(bool)
);
_postTransferHook(from, to, amount, success);
}

// Transfer from
function transfer(
address to,
uint256 amount
) external virtual returns (bool success) {
_preTransferHook(msg.sender, to, amount);
success = abi.decode(
_delegateCall(
abi.encodeCall(TokenizedStrategy.transfer, (to, amount))
),
(bool)
);
_postTransferHook(msg.sender, to, amount, success);
}
}
51 changes: 51 additions & 0 deletions src/Bases/Hooks/Hooks.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// SPDX-License-Identifier: AGPL-3.0
pragma solidity 0.8.18;

contract DepositHooks {
function _preDepositHook(
uint256 assets,
uint256 shares,
address receiver
) internal virtual {}

Check warning on line 9 in src/Bases/Hooks/Hooks.sol

View workflow job for this annotation

GitHub Actions / solidity

Code contains empty blocks

function _postDepositHook(
uint256 assets,
uint256 shares,
address receiver
) internal virtual {}

Check warning on line 15 in src/Bases/Hooks/Hooks.sol

View workflow job for this annotation

GitHub Actions / solidity

Code contains empty blocks
}

contract WithdrawHooks {
function _preWithdrawHook(
uint256 assets,
uint256 shares,
address receiver,
address owner,
uint256 maxLoss
) internal virtual {}

Check warning on line 25 in src/Bases/Hooks/Hooks.sol

View workflow job for this annotation

GitHub Actions / solidity

Code contains empty blocks

function _postWithdrawHook(
uint256 assets,
uint256 shares,
address receiver,
address owner,
uint256 maxLoss
) internal virtual {}

Check warning on line 33 in src/Bases/Hooks/Hooks.sol

View workflow job for this annotation

GitHub Actions / solidity

Code contains empty blocks
}

contract TransferHooks {
function _preTransferHook(
address from,
address to,
uint256 amount
) internal virtual {}

Check warning on line 41 in src/Bases/Hooks/Hooks.sol

View workflow job for this annotation

GitHub Actions / solidity

Code contains empty blocks

function _postTransferHook(
address from,
address to,
uint256 amount,
bool success
) internal virtual {}

Check warning on line 48 in src/Bases/Hooks/Hooks.sol

View workflow job for this annotation

GitHub Actions / solidity

Code contains empty blocks
}

contract Hooks is DepositHooks, WithdrawHooks, TransferHooks {}

Check warning on line 51 in src/Bases/Hooks/Hooks.sol

View workflow job for this annotation

GitHub Actions / solidity

Code contains empty blocks
Loading

0 comments on commit ae73e78

Please sign in to comment.