Gearbox Core
As illustrated in Architecture, Gearbox Core is a service layer which provides unified services including six component: AddressProvider, PoolRegistry, ACL, WETHGateway, AccountFactory, PriceOracle.
These services are provided by serveal smart contracts: AddressProvider, AccountFactory, ContractsRegister, WETHGateway, ACL&ACL Trait, DataCompressor and Oracles.
In this section we'll dig deeper into these smart contracts.
AddressProvider
AddressProvider keeps addresses of core contracts which is used for smart contract address discovery. Continuing from the simple example we built previously, we can start to use other functionality of AddressProvider.
note
We assume that you're running a Mainnet fork by now. Please refer to the last step in Gearbox SDK and Mainnet Forking for instructions.
Create a new source file scripts/gearbox-discovery.ts and query the latest vesion of Gearbox Contract.
Let's take a look at the code. We can see that the code queries the address of contracts register contractsRegisterAddress from addressProvider and gets the list of pools and credit managers from contractsRegister. After quering the address of AccountFactory from AddressProvider and connecting to AccountFactory, we can get the accounts stats from AccountFactory.
scripts/gearbox-discovery.tsjsxasync function main() {// If you don't specify a //url//, Ethers connects to the default// (i.e. ``http:/\/localhost:8545``)const provider = new ethers.providers.JsonRpcProvider();// The address of Gearbox's AddressProvider contractconst addressProvider = AddressProvider__factory.connect(ADDRESS_PROVIDER_ADDRESS, provider);// Start to query AddressProvider//// Get the latest version of Gearbox's contractsconst version = await addressProvider.version();console.log("version of Gearbox Contract is ", version);// Get ContractsRegisterconst contractsRegisterAddress = await addressProvider.getContractsRegister();console.log("ContractsRegisterAddress is ", contractsRegisterAddress);//******************** ContractsRegister ********************const contractsRegister = ContractsRegister__factory.connect(contractsRegisterAddress, provider);const poolList = await contractsRegister.getPools();console.log("Pool List: ", poolList);const creditManagerList = await contractsRegister.getCreditManagers();console.log("Credit Manager List: ", creditManagerList);//******************** ContractsRegister ********************// Get ACLconst ACLAddress = await addressProvider.getACL();console.log("ACL is ", ACLAddress);// Get PriceOracleconst priceOracleAddress = await addressProvider.getPriceOracle();console.log("PriceOracle is ", priceOracleAddress);// Get AccountFactoryconst accountFactoryAddress = await addressProvider.getAccountFactory();console.log("AccountFactory is ", accountFactoryAddress);//******************** AccountFactory ********************const accountFactory = AccountFactory__factory.connect(accountFactoryAddress, provider);const countCreditAccount = await accountFactory.countCreditAccounts();console.log("Count of Credit Accounts: ", countCreditAccount);const countCreditAccountInStock = await accountFactory.countCreditAccountsInStock();console.log("Count of Credit Accounts InStock: ", countCreditAccountInStock);//******************** AccountFactory ********************// Get DataCompressorconst dataCompressorAddress = await addressProvider.getDataCompressor();console.log("DataCompressor is ", dataCompressorAddress);// Get WETH Tokenconst WETHGateway = await addressProvider.getWETHGateway();console.log("WETHGateway is ", WETHGateway);}
scripts/gearbox-discovery.tsjsxasync function main() {// If you don't specify a //url//, Ethers connects to the default// (i.e. ``http:/\/localhost:8545``)const provider = new ethers.providers.JsonRpcProvider();// The address of Gearbox's AddressProvider contractconst addressProvider = AddressProvider__factory.connect(ADDRESS_PROVIDER_ADDRESS, provider);// Start to query AddressProvider//// Get the latest version of Gearbox's contractsconst version = await addressProvider.version();console.log("version of Gearbox Contract is ", version);// Get ContractsRegisterconst contractsRegisterAddress = await addressProvider.getContractsRegister();console.log("ContractsRegisterAddress is ", contractsRegisterAddress);//******************** ContractsRegister ********************const contractsRegister = ContractsRegister__factory.connect(contractsRegisterAddress, provider);const poolList = await contractsRegister.getPools();console.log("Pool List: ", poolList);const creditManagerList = await contractsRegister.getCreditManagers();console.log("Credit Manager List: ", creditManagerList);//******************** ContractsRegister ********************// Get ACLconst ACLAddress = await addressProvider.getACL();console.log("ACL is ", ACLAddress);// Get PriceOracleconst priceOracleAddress = await addressProvider.getPriceOracle();console.log("PriceOracle is ", priceOracleAddress);// Get AccountFactoryconst accountFactoryAddress = await addressProvider.getAccountFactory();console.log("AccountFactory is ", accountFactoryAddress);//******************** AccountFactory ********************const accountFactory = AccountFactory__factory.connect(accountFactoryAddress, provider);const countCreditAccount = await accountFactory.countCreditAccounts();console.log("Count of Credit Accounts: ", countCreditAccount);const countCreditAccountInStock = await accountFactory.countCreditAccountsInStock();console.log("Count of Credit Accounts InStock: ", countCreditAccountInStock);//******************** AccountFactory ********************// Get DataCompressorconst dataCompressorAddress = await addressProvider.getDataCompressor();console.log("DataCompressor is ", dataCompressorAddress);// Get WETH Tokenconst WETHGateway = await addressProvider.getWETHGateway();console.log("WETHGateway is ", WETHGateway);}
Run this code by executing this shell command:
bashnpx hardhat run scripts/gearbox-discovery.ts
bashnpx hardhat run scripts/gearbox-discovery.ts
This should produce the following output:
·-----------------|-------------· | Contract Name · Size (KB) │ ·-----------------|-------------· version of Gearbox Contract is BigNumber { value: "1" } ContractsRegister is 0xA50d4E7D8946a7c90652339CDBd262c375d54D99 ACL is 0x523dA3a8961E4dD4f6206DBf7E6c749f51796bb3 PriceOracle is 0x0e74a08443c5E39108520589176Ac12EF65AB080 AccountFactory is 0x444CD42BaEdDEB707eeD823f7177b9ABcC779C04 DataCompressor is 0x0050b1ABD1DD2D9b01ce954E663ff3DbCa9193B1 WETHGateway is 0x4F952c4C5415B2609899AbDC2F8F352F600d14D6
·-----------------|-------------· | Contract Name · Size (KB) │ ·-----------------|-------------· version of Gearbox Contract is BigNumber { value: "1" } ContractsRegister is 0xA50d4E7D8946a7c90652339CDBd262c375d54D99 ACL is 0x523dA3a8961E4dD4f6206DBf7E6c749f51796bb3 PriceOracle is 0x0e74a08443c5E39108520589176Ac12EF65AB080 AccountFactory is 0x444CD42BaEdDEB707eeD823f7177b9ABcC779C04 DataCompressor is 0x0050b1ABD1DD2D9b01ce954E663ff3DbCa9193B1 WETHGateway is 0x4F952c4C5415B2609899AbDC2F8F352F600d14D6
ContractsRegister
ContractsRegister maintains all the pools and credit managers.
The ContractsRegister can be retrieved by querying AddressProvider.
ContractsRegister exports two functions that we can use, getpools and getCreditManagers.
The gearbox-sdk allows us to import ContractsRegister__factory to perform these operations.
We'll add some code in scripts/gearbox-discovery.ts between ContractsRegister and ACL to use this functionality.
scripts/gearbox-discovery.tsjsx...// Get ContractsRegisterconst contractsRegisterAddress = await addressProvider.getContractsRegister();console.log("ContractsRegisterAddress is ", contractsRegisterAddress);//******************** ContractsRegister ********************const contractsRegister = ContractsRegister__factory.connect(contractsRegisterAddress, provider);const poolList = await contractsRegister.getPools();console.log("Pool List: ", poolList);const creditManagerList = await contractsRegister.getCreditManagers();console.log("Credit Manager List: ", creditManagerList);//******************** ContractsRegister ********************...
scripts/gearbox-discovery.tsjsx...// Get ContractsRegisterconst contractsRegisterAddress = await addressProvider.getContractsRegister();console.log("ContractsRegisterAddress is ", contractsRegisterAddress);//******************** ContractsRegister ********************const contractsRegister = ContractsRegister__factory.connect(contractsRegisterAddress, provider);const poolList = await contractsRegister.getPools();console.log("Pool List: ", poolList);const creditManagerList = await contractsRegister.getCreditManagers();console.log("Credit Manager List: ", creditManagerList);//******************** ContractsRegister ********************...
Run this code by executing this shell command:
bashnpx hardhat run scripts/gearbox-discovery.ts
bashnpx hardhat run scripts/gearbox-discovery.ts
This should produce the following output, where we can see the pool list and credit account list:
·-----------------|-------------· | Contract Name · Size (KB) │ ·-----------------|-------------· version of Gearbox Contract is BigNumber { value: "1" } ContractsRegister is 0xA50d4E7D8946a7c90652339CDBd262c375d54D99 Pool List: [ '0x24946bCbBd028D5ABb62ad9B635EB1b1a67AF668', '0x86130bDD69143D8a4E5fc50bf4323D48049E98E4', '0xB03670c20F87f2169A7c4eBE35746007e9575901', '0xB2A015c71c17bCAC6af36645DEad8c572bA08A08' ] Credit Manager List: [ '0x777E23A2AcB2fCbB35f6ccF98272d03C722Ba6EB', '0x2664cc24CBAd28749B3Dd6fC97A6B402484De527', '0x968f9a68a98819E2e6Bb910466e191A7b6cf02F0', '0xC38478B0A4bAFE964C3526EEFF534d70E1E09017' ] ACL is 0x523dA3a8961E4dD4f6206DBf7E6c749f51796bb3 PriceOracle is 0x0e74a08443c5E39108520589176Ac12EF65AB080 AccountFactory is 0x444CD42BaEdDEB707eeD823f7177b9ABcC779C04 DataCompressor is 0x0050b1ABD1DD2D9b01ce954E663ff3DbCa9193B1 WETHGateway is 0x4F952c4C5415B2609899AbDC2F8F352F600d14D6
·-----------------|-------------· | Contract Name · Size (KB) │ ·-----------------|-------------· version of Gearbox Contract is BigNumber { value: "1" } ContractsRegister is 0xA50d4E7D8946a7c90652339CDBd262c375d54D99 Pool List: [ '0x24946bCbBd028D5ABb62ad9B635EB1b1a67AF668', '0x86130bDD69143D8a4E5fc50bf4323D48049E98E4', '0xB03670c20F87f2169A7c4eBE35746007e9575901', '0xB2A015c71c17bCAC6af36645DEad8c572bA08A08' ] Credit Manager List: [ '0x777E23A2AcB2fCbB35f6ccF98272d03C722Ba6EB', '0x2664cc24CBAd28749B3Dd6fC97A6B402484De527', '0x968f9a68a98819E2e6Bb910466e191A7b6cf02F0', '0xC38478B0A4bAFE964C3526EEFF534d70E1E09017' ] ACL is 0x523dA3a8961E4dD4f6206DBf7E6c749f51796bb3 PriceOracle is 0x0e74a08443c5E39108520589176Ac12EF65AB080 AccountFactory is 0x444CD42BaEdDEB707eeD823f7177b9ABcC779C04 DataCompressor is 0x0050b1ABD1DD2D9b01ce954E663ff3DbCa9193B1 WETHGateway is 0x4F952c4C5415B2609899AbDC2F8F352F600d14D6
ACL
ACL keeps permissions for different addresses. For the moment, it keeps 2 different roles:
- PausableAdmin: Can pause and unpause contracts
- Configurator: Can configure contracts parameters
This part is mainly related to security and we can see from this article how it will be used.
WETHGateway
ETH <=> WETH wrapper for Gearbox protocol. It implements IWETHGateway interface.
AccountFactory
Reusable Credit Accounts are one of the main innovations of Gearbox. Users rent a predeployed credit account smart contract from the protocol, and thus save on deployment gas costs.

Each time, when a user opens a credit account in Gearbox protocol, CreditManager takes a pre-deployed credit account contract from the AccountFactory and when the user closes the credit account, CreditManager returns it.
If AccountFactory has no pre-deployed contracts, it clones it using https://eips.ethereum.org/EIPS/eip-1167
Advantages
Gas efficiency: This solution is much more gas-efficient, because it doesn't require creating a new contract each time and has minimal operational overhead.
Hacker-proof: Contract funds are allocated on isolated contracts which makes a possible attack more complex and less economically reasonable. Furthermore, the gearbox protocol uses anomaly detection to pause contracts and keep funds safe if suspicious behavior is found. User can protect their funds by splitting them between a few virtual accounts, and it makes the attack less economic reasonable.
Balance transparency on Etherscan: Trader or farmer could check all their transactions on Etherscan if they know at which block they start and finish virtual account renting.
Ethereum network ecology: It generates significantly less data in comparison with deployment credit contract for each new customer, and consume significantly less gas than keeping all balances in one place. As result it makes less impact on Ethereum infrastructure.
Implementation
AccountFactory supplies a Credit Account to CreditManager on demand and keeps them when they are not used.
The account factory uses a list to keep credit accounts and two pointers: head and tail.

When a user open a credit account, CreditManager will ask AccountFactory for a virtual account by calling function takeCreditAccount which takes one CreditAccount from the head pointer. When returns a CreditAccount, AccountFactory adds it to the tail.
DataCompressor
DataCompressor collects data from different contracts in order to transmit this information in an aggregated way to a dApp.
Let's list some main function in DataCompressor:
getCreditAccountList(address borrower)for getting the list ofCreditAccountDatas of a specified borrowergetCreditAccountData(address _creditManager, address borrower)for gettingCreditAccountDataof a specified borrower under a specifiedCreditManagergetCreditAccountDataExtended(address creditManager, address borrower)for gettingCreditAccountDataExtendedof a specified borrower under a specifiedCreditManager,CreditAccountDataExtendedis the extension types ofCreditAccountData, you can checkTypes.solfor more details.getCreditManagersList(address borrower)for getting list ofCreditManagerDataof a specified borrowergetPoolsList()for getting list ofPoolData
info
Datacompressor has an unstable API
Because most of the functions need a borrower address as parameter, we are unable to demo its output. You can use your (test) wallet to open an account and try to use it yourself.