{
    "Function": "_valueAt",
    "File": "contracts/openzeppelin-solidity/contracts/token/ERC20/extensions/ERC20Snapshot.sol",
    "Parent Contracts": [
        "contracts/openzeppelin-solidity/contracts/token/ERC20/ERC20.sol",
        "contracts/openzeppelin-solidity/contracts/token/ERC20/extensions/IERC20Metadata.sol",
        "contracts/openzeppelin-solidity/contracts/token/ERC20/IERC20.sol",
        "contracts/openzeppelin-solidity/contracts/utils/Context.sol"
    ],
    "High-Level Calls": [
        "Arrays"
    ],
    "Internal Calls": [
        "require(bool,string)",
        "_getCurrentSnapshotId",
        "require(bool,string)"
    ],
    "Library Calls": [
        "findUpperBound"
    ],
    "Low-Level Calls": [],
    "Code": "function _valueAt(uint256 snapshotId, Snapshots storage snapshots) private view returns (bool, uint256) {\n        require(snapshotId > 0, \"ERC20Snapshot: id is 0\");\n        require(snapshotId <= _getCurrentSnapshotId(), \"ERC20Snapshot: nonexistent id\");\n\n        // When a valid snapshot is queried, there are three possibilities:\n        //  a) The queried value was not modified after the snapshot was taken. Therefore, a snapshot entry was never\n        //  created for this id, and all stored snapshot ids are smaller than the requested one. The value that corresponds\n        //  to this id is the current one.\n        //  b) The queried value was modified after the snapshot was taken. Therefore, there will be an entry with the\n        //  requested id, and its value is the one to return.\n        //  c) More snapshots were created after the requested one, and the queried value was later modified. There will be\n        //  no entry for the requested id: the value that corresponds to it is that of the smallest snapshot id that is\n        //  larger than the requested one.\n        //\n        // In summary, we need to find an element in an array, returning the index of the smallest value that is larger if\n        // it is not found, unless said value doesn't exist (e.g. when all values are smaller). Arrays.findUpperBound does\n        // exactly this.\n\n        uint256 index = snapshots.ids.findUpperBound(snapshotId);\n\n        if (index == snapshots.ids.length) {\n            return (false, 0);\n        } else {\n            return (true, snapshots.values[index]);\n        }\n    }"
}