Skip to content

Commit

Permalink
Merge pull request #1370 from bancorprotocol/add-celo-chain
Browse files Browse the repository at this point in the history
Add celo chain
  • Loading branch information
tiagofilipenunes authored Jul 31, 2024
2 parents dd6b79f + 3566ece commit 3a1e10f
Show file tree
Hide file tree
Showing 29 changed files with 249 additions and 24 deletions.
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,8 @@ The file `common.ts` with type [`AppConfig`](src/config/types.ts) contains impor
- `name`: Network name.
- `logoUrl`: Network logo URL.
- `chainId`: Chain ID.
- `gasToken`: Gas token name, symbol, decimals, address and logoURI.
- `defaultLimitedApproval`: Optional flag to set the default ERC-20 approval to limited approval. For chains where gas is low, it is recommended to set this flag to true.
- `gasToken`: Gas token name, symbol, decimals, address and logoURI. This parameter will take priority over the `tokenListOverride`.
- `blockExplorer`: The name and URL of the block explorer to be used in the notifications and when the network is added to the injected wallet.
- `rpc`: The RPC url and headers of the network, used to add the network to the injected wallet and to fetch data from the chain.
- `defaultTokenPair`: Default token pair to be used in the app when opening the trade, explore, and simulation pages.
Expand All @@ -203,6 +204,10 @@ The file `common.ts` with type [`AppConfig`](src/config/types.ts) contains impor
- `tokenLists`: List of token lists including the uri and the parser to be used to parse the token list.
- `sdk`/`cacheTTL`: When the app loads, it will ignore any cached data if it is older than the cacheTTL time in milliseconds. If set to 0, the app will always ignore the cache data and fetch new data on load.

#### Gas token different than native token

The CarbonDeFi Contracts, Backend and SDK use an internal fixed address for the native gas token, `0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE`, hereby called `native token`. If a different `gas token` address than the `native token` address is set in `network.gasToken.address`, the app will hide the `gas token` from the token list and use the `network token` address for all token and pair searches.

### Add pairsToExchangeMapping

The file [`pairsToExchangeMapping.ts`](src/config/utils.ts) contains the mapping of pair symbols to exchange symbol to be used in the TradingView chart.
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified e2e/screenshots/strategy/overlapping/Overlapping/deposit/form.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 5 additions & 1 deletion functions/api/check/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
const BLOCKED_HOSTS = ['carbon-app-csq.pages.dev', 'carbon-app-sei.pages.dev'];
const BLOCKED_HOSTS = [
'carbon-app-csq.pages.dev',
'carbon-app-sei.pages.dev',
'carbon-app-celo.pages.dev',
];

const NO_NO_COUNTRIES = [
'BY', // Belarus
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@
"start": "vite",
"start:ethereum": "cross-env VITE_NETWORK=ethereum vite",
"start:sei": "cross-env VITE_NETWORK=sei vite",
"start:celo": "cross-env VITE_NETWORK=celo vite",
"prebuild": "yarn compile-abis",
"build": "tsc && vite build",
"serve": "vite preview",
Expand Down
13 changes: 13 additions & 0 deletions src/assets/logos/celologo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 3 additions & 4 deletions src/components/common/approval/ApproveToken.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import {
} from 'services/events/types';
import { ReactComponent as IconWarning } from 'assets/icons/warning.svg';
import config from 'config';
import seiConfig from 'config/sei/production';

type Props = {
data?: ApprovalTokenResult;
Expand All @@ -27,8 +26,6 @@ type Props = {
context?: 'depositStrategyFunds' | 'createStrategy' | 'trade';
};

const isSei = config.network.chainId === seiConfig.network.chainId;

export const ApproveToken: FC<Props> = ({
data,
isPending,
Expand All @@ -43,7 +40,9 @@ export const ApproveToken: FC<Props> = ({
const token = getTokenById(data?.address || '');
const mutation = useSetUserApproval();
// Gasprice on SEI is cheap, best practice is to use exact amount approval
const [isLimited, setIsLimited] = useState(isSei);
const [isLimited, setIsLimited] = useState(
!!config.network.defaultLimitedApproval
);
const cache = useQueryClient();
const [txBusy, setTxBusy] = useState(false);
const [txSuccess, setTxSuccess] = useState(false);
Expand Down
5 changes: 3 additions & 2 deletions src/components/debug/DebugTenderlyFaucet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import config from 'config';
import { Button } from 'components/common/button';
import { QueryKey } from 'libs/queries';
import { FormEvent } from 'react';
import { NATIVE_TOKEN_ADDRESS } from 'utils/tokens';

const TOKENS = FAUCET_TOKENS.map((tkn) => ({
address: tkn.tokenContract,
Expand All @@ -19,7 +20,7 @@ const TOKENS = FAUCET_TOKENS.map((tkn) => ({

const gasToken = config.network.gasToken;
TOKENS.push({
address: gasToken.address,
address: NATIVE_TOKEN_ADDRESS,
decimals: gasToken.decimals,
symbol: gasToken.symbol,
});
Expand All @@ -38,7 +39,7 @@ export const DebugTenderlyFaucet = () => {

await tenderlyFaucetTransferNativeToken(user);
await queryClient.invalidateQueries({
queryKey: QueryKey.balance(user, gasToken.address),
queryKey: QueryKey.balance(user, NATIVE_TOKEN_ADDRESS),
});

for (const tkn of FAUCET_TOKENS) {
Expand Down
22 changes: 15 additions & 7 deletions src/components/strategies/create/useDuplicateStrategy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,27 @@ import { StrategyType, useNavigate } from 'libs/routing';
import { Strategy } from 'libs/queries';
import { getRoundedSpread } from 'components/strategies/overlapping/utils';
import { isLimitOrder } from 'components/strategies/common/utils';
import { NATIVE_TOKEN_ADDRESS, isGasTokenToHide } from 'utils/tokens';

export const useDuplicate = (type: StrategyType) => {
const navigate = useNavigate();
return ({ base, quote, order0, order1 }: Strategy) => {
return ({ base: rawBase, quote: rawQuote, order0, order1 }: Strategy) => {
let baseAddress = rawBase.address;
let quoteAddress = rawQuote.address;

// Force native token address if gas token is different
if (isGasTokenToHide(baseAddress)) baseAddress = NATIVE_TOKEN_ADDRESS;
if (isGasTokenToHide(quoteAddress)) quoteAddress = NATIVE_TOKEN_ADDRESS;

switch (type) {
case 'disposable': {
const isBuyEmpty = !+order0.endRate;
const order = isBuyEmpty ? order1 : order0;
return navigate({
to: '/strategies/create/disposable',
search: {
base: base.address,
quote: quote.address,
base: baseAddress,
quote: quoteAddress,
min: order.startRate,
max: order.endRate,
budget: order.balance,
Expand All @@ -27,8 +35,8 @@ export const useDuplicate = (type: StrategyType) => {
return navigate({
to: '/strategies/create/overlapping',
search: {
base: base.address,
quote: quote.address,
base: baseAddress,
quote: quoteAddress,
min: order0.startRate,
max: order1.endRate,
spread: getRoundedSpread({ order0, order1 }).toString(),
Expand All @@ -39,8 +47,8 @@ export const useDuplicate = (type: StrategyType) => {
return navigate({
to: '/strategies/create/recurring',
search: {
base: base.address,
quote: quote.address,
base: baseAddress,
quote: quoteAddress,
buyMin: order0.startRate,
buyMax: order0.endRate,
buyBudget: order0.balance,
Expand Down
118 changes: 118 additions & 0 deletions src/config/celo/common.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
import { AppConfig } from 'config/types';
import IconCeloLogo from 'assets/logos/celologo.svg';

const addresses = {
CELO: '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE',
CELO_ERC20: '0x471EcE3750Da237f93B8E339c536989b8978a438',
CELO_ALFAJORES: '0xF194afDf50B03e69Bd7D057c1Aa9e10c9954E4C9',
ZERO: '0x0000000000000000000000000000000000000000',
CUSD: '0x765de816845861e75a25fca122bb6898b8b1282a',
USDC: '0xceba9300f2b948710d2653dd7b07f33a8b32118c',
USDT: '0x48065fbBE25f71C9282ddf5e1cD6D6A887483D5e',
};

export const commonConfig: AppConfig = {
mode: 'development',
appName: 'Carbon DeFi',
appUrl: 'https://celo.carbondefi.xyz',
carbonApi: 'https://celo-api.carbondefi.xyz/v1/',
selectedConnectors: ['MetaMask', 'Coinbase Wallet', 'Safe'],
blockedConnectors: ['Tailwind', 'Compass Wallet', 'Seif'],
walletConnectProjectId: '',
isSimulatorEnabled: false,
policiesLastUpdated: '27 May, 2024',
network: {
name: 'Celo Network',
logoUrl: IconCeloLogo,
chainId: 42220,
blockExplorer: {
name: 'CeloScan',
url: 'https://celoscan.io',
},
rpc: {
url: import.meta.env.VITE_CHAIN_RPC_URL || 'https://forno.celo.org',
},
defaultLimitedApproval: true,
gasToken: {
name: 'CELO (erc20)',
symbol: 'CELO (erc20)',
decimals: 18,
address: addresses.CELO_ERC20,
logoURI:
'https://raw.githubusercontent.com/celo-org/celo-token-list/main/assets/celo_logo.svg',
},
},
sdk: {
cacheTTL: 0,
},
defaultTokenPair: [addresses.CELO, addresses.USDC],
popularPairs: [
[addresses.CELO, addresses.CUSD],
[addresses.CELO, addresses.USDC],
[addresses.CELO, addresses.USDT],
],
popularTokens: {
base: [addresses.CELO, addresses.CUSD, addresses.USDT, addresses.USDC],
quote: [addresses.CELO, addresses.CUSD, addresses.USDT, addresses.USDC],
},
addresses: {
tokens: addresses,
carbon: {
carbonController: '0x6619871118D144c1c28eC3b23036FC1f0829ed3a',
voucher: '0x5E994Ac7d65d81f51a76e0bB5a236C6fDA8dBF9A',
},
},
utils: {
multicall3: {
address: '0xcA11bde05977b3631167028862bE2a173976CA11',
blockCreated: 13112599,
},
},
tokenListOverride: [
{
name: 'CELO',
symbol: 'CELO',
decimals: 18,
address: addresses.CELO,
logoURI:
'https://raw.githubusercontent.com/celo-org/celo-token-list/main/assets/celo_logo.svg',
},
{
name: 'CELO (Alfajores Testnet)',
symbol: 'CELO (Alfajores)',
decimals: 18,
address: addresses.CELO_ALFAJORES,
logoURI:
'https://raw.githubusercontent.com/celo-org/celo-token-list/main/assets/celo_logo.svg',
},
],
tokenLists: [
{
uri: 'https://raw.githubusercontent.com/celo-org/celo-token-list/main/celo.tokenlist.json',
},
],
tenderly: {
nativeTokenDonorAccount: '0xf89d7b9c864f589bbF53a82105107622B35EaA40',
faucetAmount: 1000,
faucetTokens: [
{
donorAccount: '0xD533Ca259b330c7A88f74E000a3FaEa2d63B7972',
tokenContract: addresses.CUSD,
decimals: 18,
symbol: 'CUSD',
},
{
donorAccount: '0xf6436829Cf96EA0f8BC49d300c536FCC4f84C4ED',
tokenContract: addresses.USDC,
decimals: 6,
symbol: 'USDC',
},
{
donorAccount: '0x5754284f345afc66a98fbB0a0Afe71e0F007B949',
tokenContract: addresses.USDT,
decimals: 6,
symbol: 'USDT',
},
],
},
};
8 changes: 8 additions & 0 deletions src/config/celo/development.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { AppConfig } from '../types';
import { commonConfig } from './common';

const config: AppConfig = {
...commonConfig,
mode: 'development',
};
export default config;
10 changes: 10 additions & 0 deletions src/config/celo/production.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { AppConfig } from '../types';
import { commonConfig } from './common';

const config: AppConfig = {
...commonConfig,
mode: 'production',
sentryDSN:
'https://1aaa1b99875949cdb08089743dcc1ec5@o1249488.ingest.us.sentry.io/4505074572197888',
};
export default config;
1 change: 1 addition & 0 deletions src/config/ethereum/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ export const commonConfig: AppConfig = {
rpc: {
url: 'https://ethereum-rpc.publicnode.com',
},
defaultLimitedApproval: false,
gasToken: {
name: 'Ether',
symbol: 'ETH',
Expand Down
6 changes: 6 additions & 0 deletions src/config/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import ethereumDev from './ethereum/development';
import ethereumProd from './ethereum/production';
import seiDev from './sei/development';
import seiProd from './sei/production';
import celoDev from './celo/development';
import celoProd from './celo/production';
export { pairsToExchangeMapping } from './utils';

const configs = {
Expand All @@ -13,6 +15,10 @@ const configs = {
development: seiDev,
production: seiProd,
},
celo: {
development: celoDev,
production: celoProd,
},
};
type Network = keyof typeof configs;
type Mode = 'development' | 'production';
Expand Down
1 change: 1 addition & 0 deletions src/config/sei/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ export const commonConfig: AppConfig = {
'x-apikey': 'a5063ab2',
},
},
defaultLimitedApproval: true,
gasToken: {
name: 'SEI',
symbol: 'SEI',
Expand Down
1 change: 1 addition & 0 deletions src/config/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export interface AppConfig {
headers?: Record<string, string>;
};
blockExplorer: { name: string; url: string };
defaultLimitedApproval?: boolean;
gasToken: {
name: string;
symbol: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { getUndercutStrategy } from './utils';
import { getStrategyType } from 'components/strategies/common/utils';
import { useNavigate } from '@tanstack/react-router';
import { getRoundedSpread } from 'components/strategies/overlapping/utils';
import { NATIVE_TOKEN_ADDRESS, isGasTokenToHide } from 'utils/tokens';

export type ModalDuplicateStrategyData = {
strategy: Strategy;
Expand All @@ -29,11 +30,17 @@ export const ModalDuplicateStrategy: ModalFC<ModalDuplicateStrategyData> = ({
if (strategyType === 'overlapping') {
// Reduce spread by 0.1% for overlapping strategies
const spread = getRoundedSpread(strategy) * 0.99;
// Force native token address if gas token is different
let baseAddress = strategy.base.address;
let quoteAddress = strategy.quote.address;
if (isGasTokenToHide(baseAddress)) baseAddress = NATIVE_TOKEN_ADDRESS;
if (isGasTokenToHide(quoteAddress)) quoteAddress = NATIVE_TOKEN_ADDRESS;

navigate({
to: '/strategies/create/overlapping',
search: {
base: strategy.base.address,
quote: strategy.quote.address,
base: baseAddress,
quote: quoteAddress,
min: strategy.order0.startRate,
max: strategy.order1.endRate,
spread: spread.toString(),
Expand Down
Loading

0 comments on commit 3a1e10f

Please sign in to comment.