// SPDX-License-Identifier: MIT // Gearbox Protocol. Generalized leverage for DeFi protocols // (c) Gearbox Holdings, 2022 pragma solidity ^0.8.10; struct Balance { address token; uint256 balance; } library BalanceOps { error UnknownToken(address); function copyBalance(Balance memory b) internal pure returns (Balance memory) { return Balance({ token: b.token, balance: b.balance }); } function addBalance( Balance[] memory b, address token, uint256 amount ) internal pure { b[getIndex(b, token)].balance += amount; } function subBalance( Balance[] memory b, address token, uint256 amount ) internal pure { b[getIndex(b, token)].balance -= amount; } function getBalance(Balance[] memory b, address token) internal pure returns (uint256 amount) { return b[getIndex(b, token)].balance; } function setBalance( Balance[] memory b, address token, uint256 amount ) internal pure { b[getIndex(b, token)].balance = amount; } function getIndex(Balance[] memory b, address token) internal pure returns (uint256 index) { for (uint256 i; i < b.length; ) { if (b[i].token == token) { return i; } unchecked { ++i; } } revert UnknownToken(token); } function copy(Balance[] memory b, uint256 len) internal pure returns (Balance[] memory res) { res = new Balance[](len); for (uint256 i; i < len; ) { res[i] = copyBalance(b[i]); unchecked { ++i; } } } function clone(Balance[] memory b) internal pure returns (Balance[] memory) { return copy(b, b.length); } function getModifiedAfterSwap( Balance[] memory b, address tokenFrom, uint256 amountFrom, address tokenTo, uint256 amountTo ) internal pure returns (Balance[] memory res) { res = copy(b, b.length); setBalance(res, tokenFrom, getBalance(b, tokenFrom) - amountFrom); setBalance(res, tokenTo, getBalance(b, tokenTo) + amountTo); } }