This is a complete example of how you can inspect a SAFE and also open a new one using your own proxy:
import { ethers, utils as ethersUtils } from'ethers'import { Geb, utils } from'geb.js'// Setup Ether.jsconstprovider=newethers.providers.JsonRpcProvider('http://kovan.infura.io/<API KEY>')constwallet=newethers.Wallet('0xdefiisawesome...', provider)// Create the main GEB objectconstgeb=newGeb('kovan', provider)// Get a SAFEconstsafe=awaitgeb.getSafe(4)console.log(`Safe id 4 has: ${utils.wadToFixed(safe.debt).toString()} worth of debt.`)console.log(`It will get liquidated if ETH price falls below ${(awaitsafe.liquidationPrice())?.toString()} USD.`)// Open a new SAFE, lock ETH and draw system coins in a single transaction using a proxy// Note: Before doing this you need to create your own proxy// We first need to check that the system didn't reach the debt ceiling so that we can// mint more system coins.constglobalDebt=awaitgeb.contracts.safeEngine.globalDebt()constdebtCeiling=awaitgeb.contracts.safeEngine.globalDebtCeiling()constsystemCoinsToDraw=ethersUtils.parseEther('15')if(globalDebt.add(systemCoinsToDraw).gt(debtCeiling)) {thrownewError('Debt ceiling too low, not possible to draw this amount of system coins.')}// We're good to mint some system coins! constproxy=awaitgeb.getProxyAction(wallet.address)consttx=proxy.openLockETHAndGenerateDebt(ethersUtils.parseEther('1'),// Lock 1 Etherutils.ETH_A,// Of collateral type ETH_A systemCoinsToDraw // And draw 15 system coins)tx.gasPrice =ethers.BigNumber.from('80').mul('1000000000') // Set the gas price to 80 Gweiconstpending=awaitwallet.sendTransaction(tx) // Send the transactionconsole.log(`Transaction ${pending.hash} waiting to be mined...`)awaitpending.wait() // Wait for it to be minedconsole.log('Transaction mined, safe opened!')
Additional examples
In the examples below we assume that variables are defined like in the complete example above.
constproxy=awaitgeb.getProxyAction("0xdefidream...")// You first need to approve your proxy to spend your system coinslet tx =geb.contracts.coin.approve(proxy.proxyAddress,ethers.constants.MaxUint256)awaitwallet.sendTransaction(tx)// Repay 1 system coin worth of debt for SAFE #4tx =proxy.repayDebt(4,ethersUtils.parseEther('1'))awaitwallet.sendTransaction(tx)
Complete repayment of safe debt
constproxy=awaitgeb.getProxyAction("0xdefidream...")// You first need to approve your proxy to spend your system coinslet tx =geb.contracts.coin.approve(proxy.proxyAddress,ethers.constants.MaxUint256)awaitwallet.sendTransaction(tx)// Repay all debt of SAFE #4tx =proxy.repayAllDebt(4)awaitwallet.sendTransaction(tx)
Withdraw Ether collateral
constproxy=awaitgeb.getProxyAction("0xdefidream...")// Unlock 1 ETH of collateral from SAFE #4 and transfer it to its owner consttx=proxy.freeETH(4,ethersUtils.parseEther('1'))awaitwallet.sendTransaction(tx)
Repay all debt and withdraw all collateral
constproxy=awaitgeb.getProxyAction("0xdefidream...")constsafe=awaitgeb.getSafe(4)// You first need to approve your proxy to spend your system coinslet tx =geb.contracts.coin.approve(proxy.proxyAddress,ethers.constants.MaxUint256)awaitwallet.sendTransaction(tx)// Pay back everything and get your ETH back into your walletconsttx=proxy.repayAllDebtAndFreeETH(4,safe.collateral)awaitwallet.sendTransaction(tx)
Make direct contract calls
Geb.js exposes all contract APIs of all core contracts in the Geb.contracts object. Solidity functions that are read-only (view or pure) return asynchronously the expected value from the chain. State changing functions will return a transaction object to passed to ether.js or web3.
// Fetch some system parameters from their respective contractsconstsurplusBuffer=awaitgeb.contracts.accountingEngine.surplusBuffer()const { stabilityFee } =awaitgeb.contracts.taxCollector.collateralTypes(utils.ETH_A)// Liquidate a Safeconsttx=geb.contracts.liquidationEngine.liquidateSAFE(utils.ETH_A,"0xdefidream...");awaitwallet.sendTransaction(tx)
Multicall
Useful to bundle read-only calls in a single RPC call:
const [ globalDebt,collateralInfo ] =awaitgeb.multiCall([geb.contracts.safeEngine.globalDebt(true),// !! Note the last parameter set to true.geb.contracts.safeEngine.collateralTypes(utils.ETH_A,true),])