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

RigoBlock / v3-contracts / 13261352678

11 Feb 2025 10:59AM UTC coverage: 84.94% (+2.6%) from 82.368%
13261352678

Pull #622

github

web-flow
Merge f22d260e3 into 08bd3b51b
Pull Request #622: feat: automated nav

761 of 962 branches covered (79.11%)

Branch coverage included in aggregate %.

523 of 711 new or added lines in 28 files covered. (73.56%)

18 existing lines in 5 files now uncovered.

1698 of 1933 relevant lines covered (87.84%)

44.05 hits per line

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

56.67
/contracts/protocol/libraries/SafeTransferLib.sol
1
// SPDX-License-Identifier: Apache3.0-or-later
2
pragma solidity >=0.8.28;
3

4
import {IERC20} from "../interfaces/IERC20.sol";
5

6
type Currency is address;
7

8
/// @title SafeTransferLib
9
/// @dev This library allows for safe transfer of tokens without using assembly
10
library SafeTransferLib {
11
    error ApprovalFailed(address token);
12
    error ETHTransferFailed();
13
    error TokenTransferFailed();
14
    error TokenTransferFromFailed();
15

16
    function safeTransferNative(address to, uint256 amount) internal {
17
        (bool success, ) = to.call{gas: 2300, value: amount}("");
13✔
18
        require(success, ETHTransferFailed());
13✔
19
    }
20

21
    function safeTransfer(address token, address to, uint256 amount) internal {
22
        // solhint-disable-next-line avoid-low-level-calls
23
        (bool success, bytes memory data) = token.call(abi.encodeCall(IERC20.transfer, (to, amount)));
10✔
24
        require(success && (data.length == 0 || abi.decode(data, (bool))), TokenTransferFailed());
10✔
25
    }
26

27
    function safeTransferFrom(address token, address from, address to, uint256 amount) internal {
28
        // solhint-disable-next-line avoid-low-level-calls
29
        (bool success, bytes memory data) = token.call(
23✔
30
            abi.encodeCall(IERC20.transferFrom, (from, to, amount))
31
        );
32
        require(success && (data.length == 0 || abi.decode(data, (bool))), TokenTransferFromFailed());
23✔
33
    }
34

35
    /// @dev Allows approving all ERC20 tokens, forcing approvals when needed.
36
    function safeApprove(address token, address spender, uint256 amount) internal {
37
        /*try IERC20(token).approve(spender, amount) returns (bool success) {
38
            // will revert in case of silent failure (i.e. an address without code)
39
            assert(success);
40
        } catch {
41
            // USDT on mainnet requires approval to be set to 0 before being reset again
42
            try IERC20(token).approve(spender, 0) {
43
                IERC20(token).approve(spender, amount);
44
            } catch {
45
                revert ApprovalFailed(token);
46
            }
47
        }*/
48
        // TODO: test this alternative with try/catch. make sure legacy ERC20 calls enter the catch statement
49
        // notice: the following implementation is more gas efficient for the first legacy ERC20 approval.
NEW
50
        (bool success, bytes memory data) = token.call(abi.encodeCall(IERC20.approve, (spender, amount)));
×
51
    
NEW
52
        if (!success || (data.length != 0 && !abi.decode(data, (bool)))) {
×
53
            // force approval
NEW
54
            (success, data) = token.call(abi.encodeCall(IERC20.approve, (spender, 0)));
×
NEW
55
            (success, data) = token.call(abi.encodeCall(IERC20.approve, (spender, amount)));
×
56

NEW
57
            require(success && ((data.length == 0 && token.code.length > 0) || abi.decode(data, (bool))), ApprovalFailed(token));
×
58
        }
59
    }
60

61
    function isAddressZero(address target) internal pure returns (bool) {
62
        return target == address(0);
162✔
63
    }
64
}
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