• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

delvtech / hyperdrive / 9927927593

14 Jul 2024 12:26PM UTC coverage: 92.277%. First build
9927927593

Pull #1081

github

web-flow
Merge e5af82277 into 683f2f7cd
Pull Request #1081: Added an Aave integration

120 of 142 new or added lines in 33 files covered. (84.51%)

2115 of 2292 relevant lines covered (92.28%)

376654.76 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

93.33
/contracts/src/instances/aave/AaveBase.sol
1
// SPDX-License-Identifier: Apache-2.0
2
pragma solidity 0.8.20;
3

4
import { IPool } from "aave/interfaces/IPool.sol";
5
import { ERC20 } from "openzeppelin/token/ERC20/ERC20.sol";
6
import { SafeERC20 } from "openzeppelin/token/ERC20/utils/SafeERC20.sol";
7
import { IAToken } from "../../interfaces/IAToken.sol";
8
import { IHyperdrive } from "../../interfaces/IHyperdrive.sol";
9
import { HyperdriveBase } from "../../internal/HyperdriveBase.sol";
10
import { FixedPointMath } from "../../libraries/FixedPointMath.sol";
11
import { AaveConversions } from "./AaveConversions.sol";
12

13
/// @author DELV
14
/// @title AaveBase
15
/// @notice The base contract for the Aave Hyperdrive implementation.
16
/// @dev This Hyperdrive implementation is designed to work with standard
17
///      Aave vaults. Non-standard implementations may not work correctly
18
///      and should be carefully checked.
19
/// @custom:disclaimer The language used in this code is for coding convenience
20
///                    only, and is not intended to, and does not, have any
21
///                    particular legal or regulatory significance.
22
abstract contract AaveBase is HyperdriveBase {
23
    using FixedPointMath for uint256;
24
    using SafeERC20 for ERC20;
25

26
    /// @dev The Aave vault that is this instance's yield source.
27
    IPool internal immutable _vault;
28

29
    /// @notice Instantiates the AaveHyperdrive base contract.
30
    constructor() {
31
        // Initialize the Aave vault immutable.
32
        _vault = IAToken(address(_vaultSharesToken)).POOL();
126✔
33

34
        // Approve the Aave vault with 1 wei. This ensures that all of the
35
        // subsequent approvals will be writing to a dirty storage slot.
36
        ERC20(address(_baseToken)).forceApprove(address(_vault), 1);
126✔
37
    }
38

39
    /// Yield Source ///
40

41
    /// @dev Accepts a deposit from the user in base.
42
    /// @param _baseAmount The base amount to deposit.
43
    /// @return The shares that were minted in the deposit.
44
    /// @return The amount of ETH to refund. Since this yield source isn't
45
    ///         payable, this is always zero.
46
    function _depositWithBase(
47
        uint256 _baseAmount,
48
        bytes calldata // unused
49
    ) internal override returns (uint256, uint256) {
50
        // Take custody of the deposit in base.
51
        ERC20(address(_baseToken)).safeTransferFrom(
202✔
52
            msg.sender,
53
            address(this),
54
            _baseAmount
55
        );
56

57
        // Deposit the base into the yield source.
58
        //
59
        // NOTE: We increase the required approval amount by 1 wei so that
60
        // the vault ends with an approval of 1 wei. This makes future
61
        // approvals cheaper by keeping the storage slot warm.
62
        ERC20(address(_baseToken)).forceApprove(
202✔
63
            address(_vault),
64
            _baseAmount + 1
65
        );
66
        _vault.supply(
202✔
67
            address(_baseToken), // asset
68
            _baseAmount, // amount
69
            address(this), // onBehalfOf
70
            // NOTE: Aave's referral program is inactive.
71
            0 // referralCode
72
        );
73

74
        return (_convertToShares(_baseAmount), 0);
202✔
75
    }
76

77
    /// @dev Process a deposit in vault shares.
78
    /// @param _shareAmount The vault shares amount to deposit.
79
    function _depositWithShares(
80
        uint256 _shareAmount,
81
        bytes calldata // unused _extraData
82
    ) internal override {
83
        // NOTE: We don't need to use `safeTransfer` since ATokens are
84
        // standard-compliant.
85
        //
86
        // Take custody of the deposit in vault shares.
87
        _vaultSharesToken.transferFrom(
720✔
88
            msg.sender,
89
            address(this),
90
            // NOTE: The AToken interface transfers in base, so we have to
91
            // convert the share amount to a base amount.
92
            _convertToBase(_shareAmount)
93
        );
94
    }
95

96
    /// @dev Process a withdrawal in base and send the proceeds to the
97
    ///      destination.
98
    /// @param _shareAmount The amount of vault shares to withdraw.
99
    /// @param _destination The destination of the withdrawal.
100
    /// @return amountWithdrawn The amount of base withdrawn.
101
    function _withdrawWithBase(
102
        uint256 _shareAmount,
103
        address _destination,
104
        bytes calldata // unused
105
    ) internal override returns (uint256 amountWithdrawn) {
106
        // Withdraw assets from the Aave vault to the destination.
107
        amountWithdrawn = _vault.withdraw(
200✔
108
            address(_baseToken), // asset
109
            // NOTE: Withdrawals are processed in base, so we have to convert
110
            // the share amount to a base amount.
111
            _convertToBase(_shareAmount), // amount
112
            _destination // onBehalfOf
113
        );
114

NEW
115
        return amountWithdrawn;
×
116
    }
117

118
    /// @dev Process a withdrawal in vault shares and send the proceeds to the
119
    ///      destination.
120
    /// @param _shareAmount The amount of vault shares to withdraw.
121
    /// @param _destination The destination of the withdrawal.
122
    function _withdrawWithShares(
123
        uint256 _shareAmount,
124
        address _destination,
125
        bytes calldata // unused
126
    ) internal override {
127
        // NOTE: We don't need to use `safeTransfer` since ATokens are
128
        // standard-compliant.
129
        //
130
        // Transfer vault shares to the destination.
131
        _vaultSharesToken.transfer(
201✔
132
            _destination,
133
            // NOTE: The AToken interface transfers in base, so we have to
134
            // convert the share amount to a base amount.
135
            _convertToBase(_shareAmount)
136
        );
137
    }
138

139
    /// @dev Convert an amount of vault shares to an amount of base.
140
    /// @param _shareAmount The vault shares amount.
141
    /// @return The base amount.
142
    function _convertToBase(
143
        uint256 _shareAmount
144
    ) internal view override returns (uint256) {
145
        return AaveConversions.convertToBase(_baseToken, _vault, _shareAmount);
4,251✔
146
    }
147

148
    /// @dev Convert an amount of base to an amount of vault shares.
149
    /// @param _baseAmount The base amount.
150
    /// @return The vault shares amount.
151
    function _convertToShares(
152
        uint256 _baseAmount
153
    ) internal view override returns (uint256) {
154
        return AaveConversions.convertToShares(_baseToken, _vault, _baseAmount);
603✔
155
    }
156

157
    /// @dev Gets the total amount of shares held by the pool in the yield
158
    ///      source.
159
    /// @return shareAmount The total amount of shares.
160
    function _totalShares()
161
        internal
162
        view
163
        override
164
        returns (uint256 shareAmount)
165
    {
166
        return _vaultSharesToken.balanceOf(address(this));
4✔
167
    }
168

169
    /// @dev We override the message value check since this integration is
170
    ///      not payable.
171
    function _checkMessageValue() internal view override {
172
        if (msg.value != 0) {
926✔
173
            revert IHyperdrive.NotPayable();
4✔
174
        }
175
    }
176
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc