-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add lots of JS from Nantucket and pair contract
- Loading branch information
1 parent
069fd98
commit 0d9aea9
Showing
20 changed files
with
1,623 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
{ | ||
"contracts": {}, | ||
"solidityLibs": {}, | ||
"proxies": { | ||
"CafeChi/CafeChi": [ | ||
{ | ||
"address": "0x9dB0987bAAC8EAA684Ff54F836a2368109f1761C", | ||
"kind": "NonProxy", | ||
"bytecodeHash": "5c8aa614716e91c24afbbe430b6654219ce01bb2da808322eac37cd6348cbf6b" | ||
} | ||
] | ||
}, | ||
"manifestVersion": "2.2" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,25 @@ | ||
const HDWalletProvider = require("@truffle/hdwallet-provider"); | ||
require("dotenv").config(); | ||
|
||
module.exports = { | ||
networks: { | ||
development: { | ||
protocol: 'http', | ||
host: 'localhost', | ||
ganache: { | ||
protocol: "http", | ||
host: "localhost", | ||
port: 8545, | ||
gas: 6000000, | ||
gasPrice: 45e9, | ||
networkId: '*', | ||
networkId: "*" | ||
}, | ||
}, | ||
production: { | ||
provider: () => | ||
new HDWalletProvider( | ||
process.env.ACCOUNT_SECRET, | ||
"https://mainnet.infura.io/v3/" + process.env.PROVIDER_INFURA_ID | ||
), | ||
gas: 4000000, | ||
gasPrice: 26e9, | ||
networkId: "*" | ||
} | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
const nfetch = require("node-fetch"); | ||
const Transport = require("winston-transport"); | ||
|
||
class SlackHook extends Transport { | ||
constructor(opts) { | ||
super(opts); | ||
|
||
opts = opts || {}; | ||
|
||
this.webhookUrl = opts.webhookUrl; | ||
this.formatter = opts.formatter || undefined; | ||
this.mrkdwn = opts.mrkdwn || false; | ||
} | ||
|
||
log(info, callback) { | ||
let payload = { | ||
mrkdwn: this.mrkdwn | ||
}; | ||
|
||
if (this.formatter && typeof this.formatter === "function") { | ||
let layout = this.formatter(info); | ||
|
||
// Note: Supplying `text` when `blocks` is also supplied will cause `text` | ||
// to be used as a fallback for clients/surfaces that don't support blocks | ||
payload.text = layout.text || undefined; | ||
payload.blocks = layout.blocks || undefined; | ||
payload.attachments = layout.attachments || undefined; | ||
} else { | ||
payload.text = `${info.message}`; | ||
} | ||
|
||
const params = { | ||
method: "POST", | ||
headers: { | ||
"Content-Type": "application/json" | ||
}, | ||
body: JSON.stringify(payload) | ||
}; | ||
nfetch(this.webhookUrl, params).then(callback()); | ||
} | ||
} | ||
|
||
module.exports = SlackHook; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
class Fetchable { | ||
constructor() { | ||
if (new.target === Fetchable) { | ||
throw new TypeError( | ||
"Fetchable is abstract. Please subclass to construct." | ||
); | ||
} | ||
} | ||
|
||
async fetch(withConfig) {} | ||
} | ||
|
||
module.exports = Fetchable; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
const nfetch = require("node-fetch"); | ||
|
||
const Fetchable = require("./fetchable"); | ||
|
||
class GasPrice extends Fetchable { | ||
async fetch() { | ||
const res = await nfetch(process.env.GAS_STATION_ENDPOINT, { | ||
method: "GET" | ||
}); | ||
const json = await res.json(); | ||
|
||
return { | ||
fastest: json.fastest ? Number(json.fastest) * 1e8 : null, | ||
fast: json.fast ? Number(json.fast) * 1e8 : null, | ||
average: json.average ? Number(json.average) * 1e8 : null, | ||
safeLow: json.safeLow ? Number(json.safeLow) * 1e8 : null | ||
}; | ||
} | ||
} | ||
|
||
module.exports = GasPrice; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
[ | ||
{ | ||
"inputs": [], | ||
"name": "arb", | ||
"outputs": [], | ||
"stateMutability": "nonpayable", | ||
"type": "function" | ||
}, | ||
{ | ||
"inputs": [ | ||
{ | ||
"internalType": "address", | ||
"name": "sender", | ||
"type": "address" | ||
}, | ||
{ | ||
"internalType": "uint256", | ||
"name": "amount0", | ||
"type": "uint256" | ||
}, | ||
{ | ||
"internalType": "uint256", | ||
"name": "amount1", | ||
"type": "uint256" | ||
}, | ||
{ | ||
"internalType": "bytes", | ||
"name": "data", | ||
"type": "bytes" | ||
} | ||
], | ||
"name": "uniswapV2Call", | ||
"outputs": [], | ||
"stateMutability": "nonpayable", | ||
"type": "function" | ||
}, | ||
{ | ||
"stateMutability": "payable", | ||
"type": "receive" | ||
} | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,153 @@ | ||
const Big = require("big.js"); | ||
Big.DP = 40; | ||
Big.RM = 0; | ||
|
||
const Web3Utils = require("web3-utils"); | ||
|
||
const SmartContract = require("../smartcontract"); | ||
|
||
class CafeChi extends SmartContract { | ||
arb() { | ||
return this._txFor(this._inner.methods.arb()); | ||
} | ||
|
||
|
||
liquidateSNWithPrice( | ||
messages, | ||
signatures, | ||
symbols, | ||
borrowers, | ||
repayCTokens, | ||
seizeCTokens, | ||
gasPrice, | ||
chi = false | ||
) { | ||
const cTokens = this._combineTokens(repayCTokens, seizeCTokens); | ||
let method = chi | ||
? this._inner.methods.liquidateSNWithPriceChi | ||
: this._inner.methods.liquidateSNWithPrice; | ||
method = method(messages, signatures, symbols, borrowers, cTokens); | ||
// TODO we cheat here by just estimating gas for first candidate since | ||
// that's all that TxManager cares about at the moment. | ||
const gasLimit = this._estimateGas(repayCTokens[0], seizeCTokens[0], true); | ||
return this._txFor(method, gasLimit, gasPrice); | ||
} | ||
|
||
/** | ||
* Performs liquidation on multiple accounts (SEND -- uses gas) | ||
* | ||
* @param {Array<String>} borrowers addresses of users with negative liquidity | ||
* @param {Array<String>} repayCTokens address of token to repay | ||
* @param {Array<String>} seizeCTokens address of token to seize | ||
* @param {Number} gasPrice the gas price to use, in gwei | ||
* @return {Object} the transaction object | ||
*/ | ||
liquidateSN(borrowers, repayCTokens, seizeCTokens, gasPrice, chi = false) { | ||
const cTokens = this._combineTokens(repayCTokens, seizeCTokens); | ||
let method = chi | ||
? this._inner.methods.liquidateSNChi | ||
: this._inner.methods.liquidateSN; | ||
method = method(borrowers, cTokens); | ||
// TODO we cheat here by just estimating gas for first candidate since | ||
// that's all that TxManager cares about at the moment. | ||
const gasLimit = this._estimateGas(repayCTokens[0], seizeCTokens[0]); | ||
return this._txFor(method, gasLimit, gasPrice); | ||
} | ||
|
||
liquidateSWithPrice( | ||
messages, | ||
signatures, | ||
symbols, | ||
borrower, | ||
repayCToken, | ||
seizeCToken, | ||
gasPrice, | ||
chi = false | ||
) { | ||
let method = chi | ||
? this._inner.methods.liquidateSWithPriceChi | ||
: this._inner.methods.liquidateSWithPrice; | ||
method = method( | ||
messages, | ||
signatures, | ||
symbols, | ||
borrower, | ||
repayCToken, | ||
seizeCToken | ||
); | ||
const gasLimit = this._estimateGas(repayCToken, seizeCToken, true); | ||
return this._txFor(method, gasLimit, gasPrice); | ||
} | ||
|
||
liquidateS(borrower, repayCToken, seizeCToken, gasPrice, chi = false) { | ||
let method = chi | ||
? this._inner.methods.liquidateSChi | ||
: this._inner.methods.liquidateS; | ||
method = method(borrower, repayCToken, seizeCToken); | ||
const gasLimit = this._estimateGas(repayCToken, seizeCToken); | ||
return this._txFor(method, gasLimit, gasPrice); | ||
} | ||
|
||
/** | ||
* Performs liquidation (SEND -- uses gas) | ||
* | ||
* @param {string} borrower address of any user with negative liquidity | ||
* @param {string} repayCToken address of token to repay | ||
* @param {string} seizeCToken address of token to seize | ||
* @param {Big} amount debt to repay, in units of the ordinary asset | ||
* @param {Number} gasPrice the gas price to use, in gwei | ||
* @return {Promise<Object>} the transaction object | ||
*/ | ||
liquidate(borrower, repayCToken, seizeCToken, amount, gasPrice) { | ||
const hexAmount = Web3Utils.toHex(amount.toFixed(0)); | ||
const method = this._inner.methods.liquidate( | ||
borrower, | ||
repayCToken, | ||
seizeCToken, | ||
hexAmount | ||
); | ||
const gasLimit = this._estimateGas(repayCToken, seizeCToken, false, false); | ||
return this.txFor(method, gasLimit, gasPrice); | ||
} | ||
|
||
_combineTokens(repayList, seizeList) { | ||
let cTokens = []; | ||
for (let i = 0; i < repayList.length; i++) | ||
cTokens.push(repayList[i], seizeList[i]); | ||
return cTokens; | ||
} | ||
|
||
_estimateGas( | ||
repayCToken, | ||
seizeCToken, | ||
postPrices = false, | ||
solveAmount = true | ||
) { | ||
let gas = Big(GAS_CUSHION); | ||
|
||
// NOTE: we assume everything is lowercase when comparing addresses | ||
if (repayCToken === CETH) gas = gas.plus(GAS_ETH2TOKEN); | ||
else if (seizeCToken === CETH) gas = gas.plus(GAS_TOKEN2ETH); | ||
// TODO The following conditional should really have an `or` clause to account | ||
// for cases where Uniswap has sufficient liquidity to go straight from repay | ||
// to seize without using Eth as an intermediate, but that's difficult to compute | ||
else if (repayCToken === seizeCToken) gas = gas.plus(GAS_TOKEN2TOKEN); | ||
else gas = gas.plus(GAS_TOKEN2TOKEN2ETH); | ||
|
||
if (V2S.includes(repayCToken) || V2S.includes(seizeCToken)) | ||
gas = gas.plus(GAS_V2_PENALTY); | ||
if (postPrices) gas = gas.plus(GAS_ORACLE); | ||
if (solveAmount) gas = gas.plus(GAS_COMPUTE_AMOUNT); | ||
|
||
return gas; | ||
} | ||
} | ||
|
||
const addresses = { | ||
mainnet: "0x9dB0987bAAC8EAA684Ff54F836a2368109f1761C" | ||
}; | ||
|
||
const abi = require("../abis/goldenage/cafechi.json"); | ||
for (let net in addresses) { | ||
exports[net] = new CafeChi(addresses[net], abi); | ||
} |
Oops, something went wrong.