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

RigoBlock / v3-contracts / 13349297468

15 Feb 2025 10:43PM UTC coverage: 95.531% (+1.2%) from 94.346%
13349297468

Pull #642

github

web-flow
Merge 35a9cf7e6 into da745e9a8
Pull Request #642: fix: minor fixes

881 of 970 branches covered (90.82%)

Branch coverage included in aggregate %.

45 of 47 new or added lines in 5 files covered. (95.74%)

3 existing lines in 1 file now uncovered.

1855 of 1894 relevant lines covered (97.94%)

68.82 hits per line

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

75.76
/contracts/protocol/libraries/EnumerableSet.sol
1
// SPDX-License-Identifier: Apache 2.0
2
/*
3

4
 Copyright 2025 Rigo Intl.
5

6
 Licensed under the Apache License, Version 2.0 (the "License");
7
 you may not use this file except in compliance with the License.
8
 You may obtain a copy of the License at
9

10
     http://www.apache.org/licenses/LICENSE-2.0
11

12
 Unless required by applicable law or agreed to in writing, software
13
 distributed under the License is distributed on an "AS IS" BASIS,
14
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
 See the License for the specific language governing permissions and
16
 limitations under the License.
17

18
*/
19

20
pragma solidity ^0.8.20;
21

22
import {IEOracle} from "../extensions/adapters/interfaces/IEOracle.sol";
23

24
struct AddressSet {
25
    // List of stored addresses
26
    address[] addresses;
27
    // Mapping of address to position.
28
    // Position 0 means an address has never been added before.
29
    mapping(address => uint256) positions;
30
}
31

32
/// @notice Pool initialization parameters.
33
/// @dev This struct is not visible externally and used to store/read pool init params.
34
/// @param name String of the pool name (max 32 characters).
35
/// @param symbol Bytes8 of the pool symbol (from 3 to 5 characters).
36
/// @param decimals Uint8 decimals.
37
/// @param owner Address of the pool operator.
38
/// @param unlocked Boolean the pool is locked for reentrancy check.
39
/// @param baseToken Address of the base token of the pool (0 for base currency).
40
struct Pool {
41
    string name;
42
    bytes8 symbol;
43
    uint8 decimals;
44
    address owner;
45
    bool unlocked;
46
    address baseToken;
47
}
48

49
library EnumerableSet {
50
    error AddressListExceedsMaxLength();
51
    error TokenPriceFeedDoesNotExist(address token);
52

53
    // limit size of array to prevent DOS to nav estimates
54
    uint256 private constant _MAX_UNIQUE_ADDRESSES = type(uint8).max;
55

56
    // flag for removed address
57
    uint256 private constant REMOVED_ADDRESS_FLAG = type(uint256).max;
58

59
    /// @notice Base token is never pushed to active tokens, as already stored.
60
    /// @dev Skips and returns false for base token, which is already in storage.
61
    function addUnique(AddressSet storage set, IEOracle eOracle, address token, address baseToken) internal {
62
        if (token != baseToken) {
313✔
63
            if (set.positions[token] == 0 || set.positions[token] == REMOVED_ADDRESS_FLAG) {
226!
64
                require(set.addresses.length < _MAX_UNIQUE_ADDRESSES, AddressListExceedsMaxLength());
179!
65

66
                // perform a staticcall to the oracle extension and assert token has a price feed
67
                require(eOracle.hasPriceFeed(token), TokenPriceFeedDoesNotExist(token));
179!
68

69
                // update storage
70
                set.addresses.push(token);
179✔
71
                set.positions[token] = set.addresses.length;
179✔
72
            }
73
        }
74
    }
75

76
    function remove(AddressSet storage set, address token) internal {
77
        uint256 position = set.positions[token];
1✔
78

79
        if (position != 0 && position != REMOVED_ADDRESS_FLAG) {
1!
80
            // Copy last element at index position and pop last element
81
            uint256 tokenIndex = position - 1;
1✔
82
            uint256 lastIndex = set.addresses.length - 1;
1✔
83

84
            if (tokenIndex != lastIndex) {
1!
NEW
85
                address lastToken = set.addresses[lastIndex];
×
86

87
                // Move the lastToken to the index where the token to delete is
88
                set.addresses[tokenIndex] = lastToken;
×
89
                // Update the tracked position of the lastToken (that was just moved)
90
                set.positions[lastToken] = position;
×
91
            }
92

93
            // Delete the slot where the moved token was stored
94
            set.addresses.pop();
1✔
95

96
            // Delete the tracked position for the deleted slot without clearing storage
97
            set.positions[token] = REMOVED_ADDRESS_FLAG;
1✔
98
            return;
1✔
99
        }
100
    }
101

102
    function isActive(AddressSet storage set, address token) internal view returns (bool) {
103
        uint256 position = set.positions[token];
16✔
104
        return (position != 0 && position != REMOVED_ADDRESS_FLAG);
16✔
105
    }
106
}
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

© 2026 Coveralls, Inc