Skip to content

Commit

Permalink
feat: SolvBTC (#190)
Browse files Browse the repository at this point in the history
Merge #189 before merging this in main
  • Loading branch information
palace22 authored Nov 4, 2024
1 parent d5f2ecd commit 5c4371b
Show file tree
Hide file tree
Showing 15 changed files with 212 additions and 61 deletions.
5 changes: 5 additions & 0 deletions .changeset/great-onions-watch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@folks-finance/xchain-sdk": patch
---

Added SolvBTC in Avalanche, Ethereum, Base and BSC
5 changes: 5 additions & 0 deletions .changeset/nasty-jokes-brush.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@folks-finance/xchain-sdk": patch
---

Refactored cross chain token type
16 changes: 16 additions & 0 deletions src/chains/evm/common/constants/tokens.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ export const CONTRACT_SLOT: Partial<
balanceOf: 0n,
allowance: 1n,
},
[MAINNET_FOLKS_TOKEN_ID.SolvBTC]: {
balanceOf: BigInt("37439836327923360225337895871394760624280537466773280374265222508165906222592"),
allowance: BigInt("37439836327923360225337895871394760624280537466773280374265222508165906222593"),
},
},
},
[EVM_FOLKS_CHAIN_ID.ETHEREUM]: {
Expand All @@ -39,6 +43,10 @@ export const CONTRACT_SLOT: Partial<
balanceOf: 0n,
allowance: 2n,
},
[MAINNET_FOLKS_TOKEN_ID.SolvBTC]: {
balanceOf: BigInt("37439836327923360225337895871394760624280537466773280374265222508165906222592"),
allowance: BigInt("37439836327923360225337895871394760624280537466773280374265222508165906222593"),
},
},
},
[EVM_FOLKS_CHAIN_ID.BASE]: {
Expand All @@ -51,6 +59,10 @@ export const CONTRACT_SLOT: Partial<
balanceOf: 1n,
allowance: 2n,
},
[MAINNET_FOLKS_TOKEN_ID.SolvBTC]: {
balanceOf: BigInt("37439836327923360225337895871394760624280537466773280374265222508165906222592"),
allowance: BigInt("37439836327923360225337895871394760624280537466773280374265222508165906222593"),
},
},
},
[EVM_FOLKS_CHAIN_ID.BSC]: {
Expand All @@ -63,6 +75,10 @@ export const CONTRACT_SLOT: Partial<
balanceOf: 9n,
allowance: 10n,
},
[MAINNET_FOLKS_TOKEN_ID.SolvBTC]: {
balanceOf: BigInt("37439836327923360225337895871394760624280537466773280374265222508165906222592"),
allowance: BigInt("37439836327923360225337895871394760624280537466773280374265222508165906222593"),
},
},
},
[EVM_FOLKS_CHAIN_ID.AVALANCHE_FUJI]: {
Expand Down
2 changes: 1 addition & 1 deletion src/chains/evm/common/utils/message.ts
Original file line number Diff line number Diff line change
Expand Up @@ -481,7 +481,7 @@ export async function estimateEvmCcipDataGasLimit(

export function getSendTokenStateOverride(folksChainId: FolksChainId, extraArgs: OverrideTokenData) {
const { folksTokenId, amount, address, token } = extraArgs;
if (token.type === TokenType.CIRCLE || token.type === TokenType.ERC20) {
if (token.type === TokenType.CROSS_CHAIN || token.type === TokenType.ERC20) {
const erc20Address = convertFromGenericAddress(token.address, ChainType.EVM);
return getBalanceOfStateOverride([
{
Expand Down
18 changes: 16 additions & 2 deletions src/chains/evm/hub/constants/chain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ export const HUB_CHAIN: Record<NetworkType, HubChain> = {
tokens: {
[MAINNET_FOLKS_TOKEN_ID.USDC]: {
token: {
type: TokenType.CIRCLE,
type: TokenType.CROSS_CHAIN,
adapters: [AdapterType.WORMHOLE_CCTP, AdapterType.CCIP_TOKEN],
address: convertToGenericAddress("0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E" as EvmAddress, ChainType.EVM),
decimals: 6,
},
Expand Down Expand Up @@ -179,6 +180,18 @@ export const HUB_CHAIN: Record<NetworkType, HubChain> = {
poolAddress: convertToGenericAddress("0xC2FD40D9Ec4Ae7e71068652209EB75258809e131" as EvmAddress, ChainType.EVM),
supportedLoanTypes: new Set([LoanTypeId.DEPOSIT, LoanTypeId.GENERAL]),
},
[MAINNET_FOLKS_TOKEN_ID.SolvBTC]: {
token: {
type: TokenType.CROSS_CHAIN,
adapters: [AdapterType.CCIP_TOKEN],
address: convertToGenericAddress("0xbc78D84Ba0c46dFe32cf2895a19939c86b81a777" as EvmAddress, ChainType.EVM),
decimals: 18,
},
folksTokenId: MAINNET_FOLKS_TOKEN_ID.SolvBTC,
poolId: MAINNET_POOLS[MAINNET_FOLKS_TOKEN_ID.SolvBTC],
poolAddress: convertToGenericAddress("0x307bCEC89624660Ed06C97033EDb7eF49Ab0EB2D" as EvmAddress, ChainType.EVM),
supportedLoanTypes: new Set([LoanTypeId.DEPOSIT, LoanTypeId.GENERAL]),
},
} satisfies Record<MainnetFolksTokenId, HubTokenData>,
},
[NetworkType.TESTNET]: {
Expand Down Expand Up @@ -229,7 +242,8 @@ export const HUB_CHAIN: Record<NetworkType, HubChain> = {
tokens: {
[TESTNET_FOLKS_TOKEN_ID.USDC]: {
token: {
type: TokenType.CIRCLE,
type: TokenType.CROSS_CHAIN,
adapters: [AdapterType.WORMHOLE_CCTP, AdapterType.CCIP_TOKEN],
address: convertToGenericAddress("0x5425890298aed601595a70ab815c96711a31bc65" as EvmAddress, ChainType.EVM),
decimals: 6,
},
Expand Down
10 changes: 5 additions & 5 deletions src/chains/evm/hub/utils/message.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import { MessageDirection } from "../../../../common/types/gmp.js";
import { Action } from "../../../../common/types/message.js";
import { TokenType } from "../../../../common/types/token.js";
import {
assertAdapterSupportsCrossChainToken,
assertAdapterSupportsDataMessage,
assertAdapterSupportsTokenMessage,
} from "../../../../common/utils/adapter.js";
import { getSpokeChain, getSpokeTokenData } from "../../../../common/utils/chain.js";
import {
Expand Down Expand Up @@ -67,8 +67,8 @@ export async function getHubRetryMessageExtraArgsAndAdapterFees(
const spokeTokenData = getSpokeTokenData(spokeChain, folksTokenId);
const hubTokenData = getHubTokenData(folksTokenId, network);

if (hubTokenData.token.type === TokenType.CIRCLE)
assertAdapterSupportsTokenMessage(payloadData.receiverFolksChainId, returnAdapterId);
if (hubTokenData.token.type === TokenType.CROSS_CHAIN)
assertAdapterSupportsCrossChainToken(payloadData.receiverFolksChainId, hubTokenData.token, returnAdapterId);
else assertAdapterSupportsDataMessage(payloadData.receiverFolksChainId, returnAdapterId);

const returnData: SendTokenMessageData = {
Expand Down Expand Up @@ -146,8 +146,8 @@ export async function getHubReverseMessageExtraArgsAndAdapterFees(
const spokeTokenData = getSpokeTokenData(spokeChain, folksTokenId);
const hubTokenData = getHubTokenData(folksTokenId, network);

if (hubTokenData.token.type === TokenType.CIRCLE)
assertAdapterSupportsTokenMessage(message.sourceChainId, returnAdapterId);
if (hubTokenData.token.type === TokenType.CROSS_CHAIN)
assertAdapterSupportsCrossChainToken(message.sourceChainId, hubTokenData.token, returnAdapterId);
else assertAdapterSupportsDataMessage(message.sourceChainId, returnAdapterId);

const returnData: SendTokenMessageData = {
Expand Down
12 changes: 6 additions & 6 deletions src/chains/evm/spoke/modules/folks-evm-loan.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ export const prepare = {

// get state override
let stateOverride;
if (spokeTokenData.token.type === TokenType.ERC20 || spokeTokenData.token.type === TokenType.CIRCLE) {
if (spokeTokenData.token.type === TokenType.ERC20 || spokeTokenData.token.type === TokenType.CROSS_CHAIN) {
const erc20Address = convertFromGenericAddress(spokeTokenData.token.address, ChainType.EVM);
stateOverride = getAllowanceStateOverride([
{
Expand Down Expand Up @@ -179,7 +179,7 @@ export const prepare = {

// get state override
let stateOverride;
if (spokeTokenData.token.type === TokenType.ERC20 || spokeTokenData.token.type === TokenType.CIRCLE) {
if (spokeTokenData.token.type === TokenType.ERC20 || spokeTokenData.token.type === TokenType.CROSS_CHAIN) {
const erc20Address = convertFromGenericAddress(spokeTokenData.token.address, ChainType.EVM);
stateOverride = getAllowanceStateOverride([
{
Expand Down Expand Up @@ -317,7 +317,7 @@ export const prepare = {

// get state override
let stateOverride;
if (spokeTokenData.token.type === TokenType.ERC20 || spokeTokenData.token.type === TokenType.CIRCLE) {
if (spokeTokenData.token.type === TokenType.ERC20 || spokeTokenData.token.type === TokenType.CROSS_CHAIN) {
const erc20Address = convertFromGenericAddress(spokeTokenData.token.address, ChainType.EVM);
stateOverride = getAllowanceStateOverride([
{
Expand Down Expand Up @@ -495,7 +495,7 @@ export const write = {

const spokeToken = getSpokeTokenContract(provider, spokeTokenData.spokeAddress, signer);

if (includeApprove && (token.type === TokenType.CIRCLE || token.type === TokenType.ERC20)) {
if (includeApprove && (token.type === TokenType.CROSS_CHAIN || token.type === TokenType.ERC20)) {
const approveTxId = await sendERC20Approve(
provider,
token.address,
Expand Down Expand Up @@ -531,7 +531,7 @@ export const write = {

const spokeToken = getSpokeTokenContract(provider, spokeTokenData.spokeAddress, signer);

if (includeApprove && (token.type === TokenType.CIRCLE || token.type === TokenType.ERC20)) {
if (includeApprove && (token.type === TokenType.CROSS_CHAIN || token.type === TokenType.ERC20)) {
const approveTxId = await sendERC20Approve(
provider,
token.address,
Expand Down Expand Up @@ -617,7 +617,7 @@ export const write = {

const spokeToken = getSpokeTokenContract(provider, spokeTokenData.spokeAddress, signer);

if (includeApprove && (token.type === TokenType.CIRCLE || token.type === TokenType.ERC20)) {
if (includeApprove && (token.type === TokenType.CROSS_CHAIN || token.type === TokenType.ERC20)) {
const approveTxId = await sendERC20Approve(
provider,
token.address,
Expand Down
81 changes: 74 additions & 7 deletions src/common/constants/chain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,8 @@ export const SPOKE_CHAIN: Record<NetworkType, Partial<Record<FolksChainId, Spoke
tokens: {
[MAINNET_FOLKS_TOKEN_ID.USDC]: {
token: {
type: TokenType.CIRCLE,
type: TokenType.CROSS_CHAIN,
adapters: [AdapterType.WORMHOLE_CCTP, AdapterType.CCIP_TOKEN],
address: convertToGenericAddress("0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E" as EvmAddress, ChainType.EVM),
decimals: 6,
},
Expand Down Expand Up @@ -194,6 +195,20 @@ export const SPOKE_CHAIN: Record<NetworkType, Partial<Record<FolksChainId, Spoke
ChainType.EVM,
),
},
[MAINNET_FOLKS_TOKEN_ID.SolvBTC]: {
token: {
type: TokenType.CROSS_CHAIN,
adapters: [AdapterType.CCIP_TOKEN],
address: convertToGenericAddress("0xbc78D84Ba0c46dFe32cf2895a19939c86b81a777" as EvmAddress, ChainType.EVM),
decimals: 18,
},
folksTokenId: MAINNET_FOLKS_TOKEN_ID.SolvBTC,
poolId: MAINNET_POOLS[MAINNET_FOLKS_TOKEN_ID.SolvBTC],
spokeAddress: convertToGenericAddress(
"0x9e4456f0d03a263653E01EdFC8C1447A8c3E1a5a" as EvmAddress,
ChainType.EVM,
),
},
},
},
[FOLKS_CHAIN_ID.ETHEREUM]: {
Expand Down Expand Up @@ -227,7 +242,8 @@ export const SPOKE_CHAIN: Record<NetworkType, Partial<Record<FolksChainId, Spoke
tokens: {
[MAINNET_FOLKS_TOKEN_ID.USDC]: {
token: {
type: TokenType.CIRCLE,
type: TokenType.CROSS_CHAIN,
adapters: [AdapterType.WORMHOLE_CCTP, AdapterType.CCIP_TOKEN],
address: convertToGenericAddress("0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48" as EvmAddress, ChainType.EVM),
decimals: 6,
},
Expand Down Expand Up @@ -263,6 +279,20 @@ export const SPOKE_CHAIN: Record<NetworkType, Partial<Record<FolksChainId, Spoke
ChainType.EVM,
),
},
[MAINNET_FOLKS_TOKEN_ID.SolvBTC]: {
token: {
type: TokenType.CROSS_CHAIN,
adapters: [AdapterType.CCIP_TOKEN],
address: convertToGenericAddress("0x7A56E1C57C7475CCf742a1832B028F0456652F97" as EvmAddress, ChainType.EVM),
decimals: 18,
},
folksTokenId: MAINNET_FOLKS_TOKEN_ID.SolvBTC,
poolId: MAINNET_POOLS[MAINNET_FOLKS_TOKEN_ID.SolvBTC],
spokeAddress: convertToGenericAddress(
"0xD4f7fA03A4E8063825840C083Abb42CE327a3a38" as EvmAddress,
ChainType.EVM,
),
},
},
},
[FOLKS_CHAIN_ID.BASE]: {
Expand Down Expand Up @@ -296,7 +326,8 @@ export const SPOKE_CHAIN: Record<NetworkType, Partial<Record<FolksChainId, Spoke
tokens: {
[MAINNET_FOLKS_TOKEN_ID.USDC]: {
token: {
type: TokenType.CIRCLE,
type: TokenType.CROSS_CHAIN,
adapters: [AdapterType.WORMHOLE_CCTP, AdapterType.CCIP_TOKEN],
address: convertToGenericAddress("0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913" as EvmAddress, ChainType.EVM),
decimals: 6,
},
Expand Down Expand Up @@ -332,6 +363,20 @@ export const SPOKE_CHAIN: Record<NetworkType, Partial<Record<FolksChainId, Spoke
ChainType.EVM,
),
},
[MAINNET_FOLKS_TOKEN_ID.SolvBTC]: {
token: {
type: TokenType.CROSS_CHAIN,
adapters: [AdapterType.CCIP_TOKEN],
address: convertToGenericAddress("0x3B86Ad95859b6AB773f55f8d94B4b9d443EE931f" as EvmAddress, ChainType.EVM),
decimals: 18,
},
folksTokenId: MAINNET_FOLKS_TOKEN_ID.SolvBTC,
poolId: MAINNET_POOLS[MAINNET_FOLKS_TOKEN_ID.SolvBTC],
spokeAddress: convertToGenericAddress(
"0xe0C45Ab4295E96eC1259D787E2eD22C16a3D0d8f" as EvmAddress,
ChainType.EVM,
),
},
},
},
[FOLKS_CHAIN_ID.BSC]: {
Expand All @@ -353,6 +398,10 @@ export const SPOKE_CHAIN: Record<NetworkType, Partial<Record<FolksChainId, Spoke
"0x5C60f12838b8E3EEB525F299cD7C454c989dd04e" as EvmAddress,
ChainType.EVM,
),
[AdapterType.CCIP_TOKEN]: convertToGenericAddress(
"0x802063A23E78D0f5D158feaAc605028Ee490b03b" as EvmAddress,
ChainType.EVM,
),
},
tokens: {
[MAINNET_FOLKS_TOKEN_ID.BNB]: {
Expand Down Expand Up @@ -393,6 +442,20 @@ export const SPOKE_CHAIN: Record<NetworkType, Partial<Record<FolksChainId, Spoke
ChainType.EVM,
),
},
[MAINNET_FOLKS_TOKEN_ID.SolvBTC]: {
token: {
type: TokenType.CROSS_CHAIN,
adapters: [AdapterType.CCIP_TOKEN],
address: convertToGenericAddress("0x4aae823a6a0b376De6A78e74eCC5b079d38cBCf7" as EvmAddress, ChainType.EVM),
decimals: 18,
},
folksTokenId: MAINNET_FOLKS_TOKEN_ID.SolvBTC,
poolId: MAINNET_POOLS[MAINNET_FOLKS_TOKEN_ID.SolvBTC],
spokeAddress: convertToGenericAddress(
"0x7218Bd1050D41A9ECfc517abdd294FB8116aEe81" as EvmAddress,
ChainType.EVM,
),
},
},
},
} satisfies Record<MainnetFolksChainId, SpokeChain>,
Expand All @@ -416,7 +479,8 @@ export const SPOKE_CHAIN: Record<NetworkType, Partial<Record<FolksChainId, Spoke
tokens: {
[TESTNET_FOLKS_TOKEN_ID.USDC]: {
token: {
type: TokenType.CIRCLE,
type: TokenType.CROSS_CHAIN,
adapters: [AdapterType.WORMHOLE_CCTP, AdapterType.CCIP_TOKEN],
address: convertToGenericAddress("0x5425890298aed601595a70ab815c96711a31bc65" as EvmAddress, ChainType.EVM),
decimals: 6,
},
Expand Down Expand Up @@ -472,7 +536,8 @@ export const SPOKE_CHAIN: Record<NetworkType, Partial<Record<FolksChainId, Spoke
tokens: {
[TESTNET_FOLKS_TOKEN_ID.USDC]: {
token: {
type: TokenType.CIRCLE,
type: TokenType.CROSS_CHAIN,
adapters: [AdapterType.WORMHOLE_CCTP, AdapterType.CCIP_TOKEN],
address: convertToGenericAddress("0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238" as EvmAddress, ChainType.EVM),
decimals: 6,
},
Expand Down Expand Up @@ -541,7 +606,8 @@ export const SPOKE_CHAIN: Record<NetworkType, Partial<Record<FolksChainId, Spoke
tokens: {
[TESTNET_FOLKS_TOKEN_ID.USDC]: {
token: {
type: TokenType.CIRCLE,
type: TokenType.CROSS_CHAIN,
adapters: [AdapterType.WORMHOLE_CCTP, AdapterType.CCIP_TOKEN],
address: convertToGenericAddress("0x036CbD53842c5426634e7929541eC2318f3dCF7e" as EvmAddress, ChainType.EVM),
decimals: 6,
},
Expand Down Expand Up @@ -632,7 +698,8 @@ export const SPOKE_CHAIN: Record<NetworkType, Partial<Record<FolksChainId, Spoke
tokens: {
[TESTNET_FOLKS_TOKEN_ID.USDC]: {
token: {
type: TokenType.CIRCLE,
type: TokenType.CROSS_CHAIN,
adapters: [AdapterType.WORMHOLE_CCTP, AdapterType.CCIP_TOKEN],
address: convertToGenericAddress("0x75faf114eafb1BDbe2F0316DF893fd58CE46AA4d" as EvmAddress, ChainType.EVM),
decimals: 6,
},
Expand Down
3 changes: 2 additions & 1 deletion src/common/constants/pool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export const MAINNET_POOLS = {
[MAINNET_FOLKS_TOKEN_ID.BNB]: 10,
[MAINNET_FOLKS_TOKEN_ID.ETHB_bsc]: 11,
[MAINNET_FOLKS_TOKEN_ID.BTCB_bsc]: 12,
[MAINNET_FOLKS_TOKEN_ID.SolvBTC]: 15,
} as const satisfies Record<MainnetFolksTokenId, number>;

export const TESTNET_POOLS = {
Expand All @@ -28,5 +29,5 @@ export const TESTNET_POOLS = {
} as const satisfies Record<TestnetFolksTokenId, number>;

export const FOLKS_TOKEN_IDS_FROM_POOL = Object.fromEntries(
Object.entries(TESTNET_POOLS).map(([token, poolId]) => [poolId, token]),
Object.entries({ ...MAINNET_POOLS, ...TESTNET_POOLS }).map(([token, poolId]) => [poolId, token]),
) as Partial<Record<number, FolksTokenId>>;
6 changes: 5 additions & 1 deletion src/common/constants/token.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,8 @@ import { MAINNET_FOLKS_TOKEN_ID, TESTNET_FOLKS_TOKEN_ID } from "../types/token.j

import type { FolksTokenId } from "../types/token.js";

export const CIRCLE_FOLKS_TOKEN_ID: Array<FolksTokenId> = [MAINNET_FOLKS_TOKEN_ID.USDC, TESTNET_FOLKS_TOKEN_ID.USDC];
export const CROSS_CHAIN_FOLKS_TOKEN_ID: Array<FolksTokenId> = [
MAINNET_FOLKS_TOKEN_ID.USDC,
MAINNET_FOLKS_TOKEN_ID.SolvBTC,
TESTNET_FOLKS_TOKEN_ID.USDC,
];
Loading

0 comments on commit 5c4371b

Please sign in to comment.