Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@angleprotocol:registry=https://npm.pkg.github.com
1 change: 1 addition & 0 deletions foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@
src = "src"
out = "out"
libs = ["lib"]
fs_permissions = [{ access = "read", path = "./node_modules/@angleprotocol/sdk/dist/src/registry/registry.json" }]

# See more config options https://github.com/foundry-rs/foundry/blob/master/crates/config/README.md#all-options
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@
"author": "Angle Labs, Inc.",
"license": "GPL-3.0",
"dependencies": {
"@angleprotocol/sdk": "^0.37.1"
"@angleprotocol/sdk": "^2.34.7"
}
}
501 changes: 397 additions & 104 deletions src/CommonUtils.sol

Large diffs are not rendered by default.

75 changes: 53 additions & 22 deletions src/Constants.sol
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ enum ContractType {
CoreMerkl,
DistributionCreator,
Distributor,
Disputer,
FeeDistributor,
GaugeController,
Governor,
Expand All @@ -42,29 +43,59 @@ enum ContractType {
veBoost,
veBoostProxy,
ProxyAdminGuardian,
FlashLoan
FlashLoan,
MultiBlockHarvester,
GenericHarvester,
Harvester,
Rebalancer,
MulticallWithFailure,
OracleNativeUSD,
Swapper,
AngleHelpers
}

uint256 constant CHAIN_FORK = 0;
uint256 constant CHAIN_ETHEREUM = 1;
uint256 constant CHAIN_ARBITRUM = 42161;
uint256 constant CHAIN_AVALANCHE = 43114;
uint256 constant CHAIN_OPTIMISM = 10;
uint256 constant CHAIN_POLYGON = 137;
uint256 constant CHAIN_FANTOM = 250;
uint256 constant CHAIN_GNOSIS = 100;
uint256 constant CHAIN_BNB = 56;
uint256 constant CHAIN_CELO = 42220;
uint256 constant CHAIN_POLYGONZKEVM = 1101;
uint256 constant CHAIN_BASE = 8453;
uint256 constant CHAIN_LINEA = 59144;
uint256 constant CHAIN_MANTLE = 5000;
uint256 constant CHAIN_AURORA = 1313161554;
uint256 constant CHAIN_MODE = 34443;
uint256 constant CHAIN_BLAST = 81457;
uint256 constant CHAIN_XLAYER = 196;
library Constants {
uint256 constant CHAIN_FORK = 0;
uint256 constant CHAIN_ETHEREUM = 1;
uint256 constant CHAIN_ARBITRUM = 42161;
uint256 constant CHAIN_AVALANCHE = 43114;
uint256 constant CHAIN_OPTIMISM = 10;
uint256 constant CHAIN_POLYGON = 137;
uint256 constant CHAIN_FANTOM = 250;
uint256 constant CHAIN_GNOSIS = 100;
uint256 constant CHAIN_BNB = 56;
uint256 constant CHAIN_CELO = 42220;
uint256 constant CHAIN_POLYGONZKEVM = 1101;
uint256 constant CHAIN_BASE = 8453;
uint256 constant CHAIN_LINEA = 59144;
uint256 constant CHAIN_MANTLE = 5000;
uint256 constant CHAIN_AURORA = 1313161554;
uint256 constant CHAIN_MODE = 34443;
uint256 constant CHAIN_BLAST = 81457;
uint256 constant CHAIN_XLAYER = 196;
uint256 constant CHAIN_THUNDERCORE = 108;
uint256 constant CHAIN_COREDAO = 1116;
uint256 constant CHAIN_TAIKO = 167000;
uint256 constant CHAIN_FUSE = 122;
uint256 constant CHAIN_IMMUTABLE = 13371;
uint256 constant CHAIN_SCROLL = 534352;
uint256 constant CHAIN_MANTA = 169;
uint256 constant CHAIN_SEI = 1329;
uint256 constant CHAIN_FRAXTAL = 252;
uint256 constant CHAIN_ASTAR = 592;
uint256 constant CHAIN_ASTARZKEVM = 3776;
uint256 constant CHAIN_ROOTSTOCK = 30;
uint256 constant CHAIN_MOONBEAM = 1284;
uint256 constant CHAIN_SKALE = 2046399126;
uint256 constant CHAIN_WORLDCHAIN = 480;
uint256 constant CHAIN_LISK = 1135;
uint256 constant CHAIN_ETHERLINK = 42793;
uint256 constant CHAIN_ARTHERA = 10242;
uint256 constant CHAIN_SWELL = 1923;

uint256 constant BASE_18 = 1e18;
uint256 constant BASE_9 = 1e9;
uint256 constant BASE_18 = 1e18;
uint256 constant BASE_9 = 1e9;

address constant IMMUTABLE_CREATE2_FACTORY_ADDRESS = 0x0000000000FFe8B47B3e2130213B802212439497;
address constant IMMUTABLE_CREATE2_FACTORY_ADDRESS =
0x0000000000FFe8B47B3e2130213B802212439497;
}
157 changes: 157 additions & 0 deletions src/JsonReader.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.17;

import {Script} from "forge-std/Script.sol";
import {stdJson} from "forge-std/StdJson.sol";
import {ContractType} from "./Constants.sol";

contract JsonReader is Script {
using stdJson for string;

error FileNotFound(string path);
error ValueNotFound(string path, string key);
error ChainNotSupported(uint256 chainId);

// Mapping of chain IDs to their names
mapping(uint256 => string) internal chainNames;

/// @notice Gets the network-specific config path
/// @return The full path to the network config file
function getPath() public view returns (string memory) {
string memory root = vm.projectRoot();
return
string.concat(
root,
"/node_modules/@angleprotocol/sdk/dist/src/registry/registry.json"
);
}

/// @notice Reads an address value from the network's JSON file
/// @param chainId The chain ID
/// @param key The JSON key to read
/// @return The address value
function readAddress(
uint256 chainId,
string memory key
) public view returns (address) {
string memory path = getPath();
return
readAddressFromPath(
path,
string.concat(vm.toString(chainId), ".", key)
);
}

/// @notice Reads a string value from the network's JSON file
/// @param chainId The chain ID
/// @param key The JSON key to read
/// @return The string value
function readString(
uint256 chainId,
string memory key
) public view returns (string memory) {
string memory path = getPath();
return
readStringFromPath(
path,
string.concat(vm.toString(chainId), ".", key)
);
}

/// @notice Reads a uint256 value from the network's JSON file
/// @param chainId The chain ID
/// @param key The JSON key to read
/// @return The uint256 value
function readUint(
uint256 chainId,
string memory key
) public view returns (uint256) {
string memory path = getPath();
return
readUintFromPath(
path,
string.concat(vm.toString(chainId), ".", key)
);
}

/// @notice Reads a string array from the network's JSON file
/// @param chainId The chain ID
/// @param key The JSON key to read
/// @return The string array
function readStringArray(
uint256 chainId,
string memory key
) public view returns (string[] memory) {
string memory path = getPath();
return
readStringArrayFromPath(
path,
string.concat(vm.toString(chainId), ".", key)
);
}

// Direct path reading functions
function readAddressFromPath(
string memory path,
string memory key
) public view returns (address) {
string memory json = readJsonFile(path);
bytes memory raw = json.parseRaw(string.concat(".", key));
if (raw.length == 0) revert ValueNotFound(path, key);
return bytesToAddress(raw);
}

function readStringFromPath(
string memory path,
string memory key
) public view returns (string memory) {
string memory json = readJsonFile(path);
bytes memory raw = json.parseRaw(string.concat(".", key));
if (raw.length == 0) revert ValueNotFound(path, key);
return string(raw);
}

function readUintFromPath(
string memory path,
string memory key
) public view returns (uint256) {
string memory json = readJsonFile(path);
bytes memory raw = json.parseRaw(string.concat(".", key));
if (raw.length == 0) revert ValueNotFound(path, key);
return abi.decode(raw, (uint256));
}

function readStringArrayFromPath(
string memory path,
string memory key
) public view returns (string[] memory) {
string memory json = readJsonFile(path);
bytes memory raw = json.parseRaw(string.concat(".", key));
if (raw.length == 0) revert ValueNotFound(path, key);
return abi.decode(raw, (string[]));
}

/// @notice Reads a JSON file from the given path
/// @param path The path to the JSON file
/// @return The JSON content as a string
function readJsonFile(
string memory path
) public view returns (string memory) {
try vm.readFile(path) returns (string memory json) {
return json;
} catch {
revert FileNotFound(path);
}
}

/// @notice Utility function to convert bytes to address
/// @param bys Bytes to convert
/// @return addr Resulting address
function bytesToAddress(
bytes memory bys
) private pure returns (address addr) {
assembly {
addr := mload(add(bys, 32))
}
}
}
29 changes: 23 additions & 6 deletions src/RouterSwapper.sol
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.0;

import { SafeERC20, IERC20 } from "oz/token/ERC20/utils/SafeERC20.sol";
import {SafeERC20, IERC20} from "oz/token/ERC20/utils/SafeERC20.sol";

/// @title Swapper
/// @author Angle Labs, Inc.
Expand Down Expand Up @@ -57,7 +57,10 @@ abstract contract RouterSwapper {
CONSTRUCTOR
//////////////////////////////////////////////////////////////*/

constructor(address initialSwapRouter, address initialTokenTransferAddress) {
constructor(
address initialSwapRouter,
address initialTokenTransferAddress
) {
swapRouter = initialSwapRouter;
tokenTransferAddress = initialTokenTransferAddress;
}
Expand All @@ -70,7 +73,9 @@ abstract contract RouterSwapper {
* @notice Set the router/aggregator address
* @param newSwapRouter address of the new router/aggregator
*/
function setSwapRouter(address newSwapRouter) public virtual noZeroAddress(newSwapRouter) {
function setSwapRouter(
address newSwapRouter
) public virtual noZeroAddress(newSwapRouter) {
swapRouter = newSwapRouter;

emit SwapRouterUpdated(newSwapRouter);
Expand Down Expand Up @@ -98,7 +103,11 @@ abstract contract RouterSwapper {
* @param spender address of the router/aggregator
* @param amount amount to approve
*/
function _approveTokenIfNeeded(address token, address spender, uint256 amount) internal {
function _approveTokenIfNeeded(
address token,
address spender,
uint256 amount
) internal {
uint256 allowance = IERC20(token).allowance(address(this), spender);
if (allowance < amount) {
IERC20(token).safeIncreaseAllowance(spender, amount - allowance);
Expand Down Expand Up @@ -128,7 +137,11 @@ abstract contract RouterSwapper {
* @param callDatas array of bytes to call the router/aggregator
* @param amounts array of amounts to swap
*/
function _swapCalldata(address[] calldata tokens, bytes[] calldata callDatas, uint256[] calldata amounts) internal {
function _swapCalldata(
address[] calldata tokens,
bytes[] calldata callDatas,
uint256[] calldata amounts
) internal {
uint256 length = tokens.length;
for (uint256 i; i < length; ++i) {
_approveTokenIfNeeded(tokens[i], tokenTransferAddress, amounts[i]);
Expand All @@ -142,7 +155,11 @@ abstract contract RouterSwapper {
* @param callDatas array of bytes to call the router/aggregator
* @param amounts array of amounts to swap
*/
function _swap(address[] memory tokens, bytes[] memory callDatas, uint256[] memory amounts) internal {
function _swap(
address[] memory tokens,
bytes[] memory callDatas,
uint256[] memory amounts
) internal {
uint256 length = tokens.length;
for (uint256 i; i < length; ++i) {
_approveTokenIfNeeded(tokens[i], tokenTransferAddress, amounts[i]);
Expand Down
Loading