Last active
January 23, 2022 08:40
-
-
Save richardliang/f7b136c2e3f70f5310bbef102446707d to your computer and use it in GitHub Desktop.
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
const { DefenderRelaySigner, DefenderRelayProvider } = require('defender-relay-client/lib/ethers'); | |
const { Relayer } = require('defender-relay-client'); | |
const { ethers } = require("ethers"); | |
const abi = [{"inputs":[{"internalType":"contract IBaseManager","name":"_manager","type":"address"},{"components":[{"internalType":"contract ISetToken","name":"setToken","type":"address"},{"internalType":"contract IPerpV2LeverageModule","name":"perpV2LeverageModule","type":"address"},{"internalType":"contract IAccountBalance","name":"perpV2AccountBalance","type":"address"},{"internalType":"contract IChainlinkAggregatorV3","name":"basePriceOracle","type":"address"},{"internalType":"contract IChainlinkAggregatorV3","name":"quotePriceOracle","type":"address"},{"internalType":"address","name":"virtualBaseAddress","type":"address"},{"internalType":"address","name":"virtualQuoteAddress","type":"address"}],"internalType":"struct PerpV2LeverageStrategyExtension.ContractSettings","name":"_strategy","type":"tuple"},{"components":[{"internalType":"int256","name":"targetLeverageRatio","type":"int256"},{"internalType":"int256","name":"minLeverageRatio","type":"int256"},{"internalType":"int256","name":"maxLeverageRatio","type":"int256"},{"internalType":"uint256","name":"recenteringSpeed","type":"uint256"},{"internalType":"uint256","name":"rebalanceInterval","type":"uint256"}],"internalType":"struct PerpV2LeverageStrategyExtension.MethodologySettings","name":"_methodology","type":"tuple"},{"components":[{"internalType":"uint256","name":"slippageTolerance","type":"uint256"},{"internalType":"uint256","name":"twapCooldownPeriod","type":"uint256"}],"internalType":"struct PerpV2LeverageStrategyExtension.ExecutionSettings","name":"_execution","type":"tuple"},{"components":[{"internalType":"uint256","name":"etherReward","type":"uint256"},{"internalType":"int256","name":"incentivizedLeverageRatio","type":"int256"},{"internalType":"uint256","name":"incentivizedSlippageTolerance","type":"uint256"},{"internalType":"uint256","name":"incentivizedTwapCooldownPeriod","type":"uint256"}],"internalType":"struct PerpV2LeverageStrategyExtension.IncentiveSettings","name":"_incentive","type":"tuple"},{"components":[{"internalType":"uint256","name":"twapMaxTradeSize","type":"uint256"},{"internalType":"uint256","name":"incentivizedTwapMaxTradeSize","type":"uint256"}],"internalType":"struct PerpV2LeverageStrategyExtension.ExchangeSettings","name":"_exchange","type":"tuple"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bool","name":"_status","type":"bool"}],"name":"AnyoneCallableUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_caller","type":"address"},{"indexed":false,"internalType":"bool","name":"_status","type":"bool"}],"name":"CallerStatusUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"int256","name":"_currentLeverageRatio","type":"int256"},{"indexed":false,"internalType":"int256","name":"_newLeverageRatio","type":"int256"},{"indexed":false,"internalType":"int256","name":"_chunkRebalanceNotional","type":"int256"},{"indexed":false,"internalType":"int256","name":"_totalRebalanceNotional","type":"int256"}],"name":"Disengaged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"int256","name":"_currentLeverageRatio","type":"int256"},{"indexed":false,"internalType":"int256","name":"_newLeverageRatio","type":"int256"},{"indexed":false,"internalType":"int256","name":"_chunkRebalanceNotional","type":"int256"},{"indexed":false,"internalType":"int256","name":"_totalRebalanceNotional","type":"int256"}],"name":"Engaged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_twapMaxTradeSize","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_incentivizedTwapMaxTradeSize","type":"uint256"}],"name":"ExchangeSettingsUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_twapCooldownPeriod","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_slippageTolerance","type":"uint256"}],"name":"ExecutionSettingsUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_etherReward","type":"uint256"},{"indexed":false,"internalType":"int256","name":"_incentivizedLeverageRatio","type":"int256"},{"indexed":false,"internalType":"uint256","name":"_incentivizedSlippageTolerance","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_incentivizedTwapCooldownPeriod","type":"uint256"}],"name":"IncentiveSettingsUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"int256","name":"_targetLeverageRatio","type":"int256"},{"indexed":false,"internalType":"int256","name":"_minLeverageRatio","type":"int256"},{"indexed":false,"internalType":"int256","name":"_maxLeverageRatio","type":"int256"},{"indexed":false,"internalType":"uint256","name":"_recenteringSpeed","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_rebalanceInterval","type":"uint256"}],"name":"MethodologySettingsUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"int256","name":"_currentLeverageRatio","type":"int256"},{"indexed":false,"internalType":"int256","name":"_newLeverageRatio","type":"int256"},{"indexed":false,"internalType":"int256","name":"_chunkRebalanceNotional","type":"int256"},{"indexed":false,"internalType":"int256","name":"_totalRebalanceNotional","type":"int256"}],"name":"RebalanceIterated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"int256","name":"_currentLeverageRatio","type":"int256"},{"indexed":false,"internalType":"int256","name":"_newLeverageRatio","type":"int256"},{"indexed":false,"internalType":"int256","name":"_chunkRebalanceNotional","type":"int256"},{"indexed":false,"internalType":"int256","name":"_totalRebalanceNotional","type":"int256"}],"name":"Rebalanced","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"int256","name":"_currentLeverageRatio","type":"int256"},{"indexed":false,"internalType":"int256","name":"_newLeverageRatio","type":"int256"},{"indexed":false,"internalType":"int256","name":"_rebalanceNotional","type":"int256"},{"indexed":false,"internalType":"uint256","name":"_etherIncentive","type":"uint256"}],"name":"RipcordCalled","type":"event"},{"inputs":[],"name":"anyoneCallable","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"callAllowList","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_collateralUnits","type":"uint256"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"disengage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"engage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getChunkRebalanceNotional","outputs":[{"internalType":"int256","name":"size","type":"int256"},{"internalType":"address","name":"sellAsset","type":"address"},{"internalType":"address","name":"buyAsset","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCurrentEtherIncentive","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCurrentLeverageRatio","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getExchangeSettings","outputs":[{"components":[{"internalType":"uint256","name":"twapMaxTradeSize","type":"uint256"},{"internalType":"uint256","name":"incentivizedTwapMaxTradeSize","type":"uint256"}],"internalType":"struct PerpV2LeverageStrategyExtension.ExchangeSettings","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getExecution","outputs":[{"components":[{"internalType":"uint256","name":"slippageTolerance","type":"uint256"},{"internalType":"uint256","name":"twapCooldownPeriod","type":"uint256"}],"internalType":"struct PerpV2LeverageStrategyExtension.ExecutionSettings","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getIncentive","outputs":[{"components":[{"internalType":"uint256","name":"etherReward","type":"uint256"},{"internalType":"int256","name":"incentivizedLeverageRatio","type":"int256"},{"internalType":"uint256","name":"incentivizedSlippageTolerance","type":"uint256"},{"internalType":"uint256","name":"incentivizedTwapCooldownPeriod","type":"uint256"}],"internalType":"struct PerpV2LeverageStrategyExtension.IncentiveSettings","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMethodology","outputs":[{"components":[{"internalType":"int256","name":"targetLeverageRatio","type":"int256"},{"internalType":"int256","name":"minLeverageRatio","type":"int256"},{"internalType":"int256","name":"maxLeverageRatio","type":"int256"},{"internalType":"uint256","name":"recenteringSpeed","type":"uint256"},{"internalType":"uint256","name":"rebalanceInterval","type":"uint256"}],"internalType":"struct PerpV2LeverageStrategyExtension.MethodologySettings","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getStrategy","outputs":[{"components":[{"internalType":"contract ISetToken","name":"setToken","type":"address"},{"internalType":"contract IPerpV2LeverageModule","name":"perpV2LeverageModule","type":"address"},{"internalType":"contract IAccountBalance","name":"perpV2AccountBalance","type":"address"},{"internalType":"contract IChainlinkAggregatorV3","name":"basePriceOracle","type":"address"},{"internalType":"contract IChainlinkAggregatorV3","name":"quotePriceOracle","type":"address"},{"internalType":"address","name":"virtualBaseAddress","type":"address"},{"internalType":"address","name":"virtualQuoteAddress","type":"address"}],"internalType":"struct PerpV2LeverageStrategyExtension.ContractSettings","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"iterateRebalance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"lastTradeTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"manager","outputs":[{"internalType":"contract IBaseManager","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rebalance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"ripcord","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"twapMaxTradeSize","type":"uint256"},{"internalType":"uint256","name":"incentivizedTwapMaxTradeSize","type":"uint256"}],"internalType":"struct PerpV2LeverageStrategyExtension.ExchangeSettings","name":"_newExchangeSettings","type":"tuple"}],"name":"setExchangeSettings","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"slippageTolerance","type":"uint256"},{"internalType":"uint256","name":"twapCooldownPeriod","type":"uint256"}],"internalType":"struct PerpV2LeverageStrategyExtension.ExecutionSettings","name":"_newExecutionSettings","type":"tuple"}],"name":"setExecutionSettings","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"etherReward","type":"uint256"},{"internalType":"int256","name":"incentivizedLeverageRatio","type":"int256"},{"internalType":"uint256","name":"incentivizedSlippageTolerance","type":"uint256"},{"internalType":"uint256","name":"incentivizedTwapCooldownPeriod","type":"uint256"}],"internalType":"struct PerpV2LeverageStrategyExtension.IncentiveSettings","name":"_newIncentiveSettings","type":"tuple"}],"name":"setIncentiveSettings","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"int256","name":"targetLeverageRatio","type":"int256"},{"internalType":"int256","name":"minLeverageRatio","type":"int256"},{"internalType":"int256","name":"maxLeverageRatio","type":"int256"},{"internalType":"uint256","name":"recenteringSpeed","type":"uint256"},{"internalType":"uint256","name":"rebalanceInterval","type":"uint256"}],"internalType":"struct PerpV2LeverageStrategyExtension.MethodologySettings","name":"_newMethodologySettings","type":"tuple"}],"name":"setMethodologySettings","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"shouldRebalance","outputs":[{"internalType":"enum PerpV2LeverageStrategyExtension.ShouldRebalance","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"int256","name":"_customMinLeverageRatio","type":"int256"},{"internalType":"int256","name":"_customMaxLeverageRatio","type":"int256"}],"name":"shouldRebalanceWithBounds","outputs":[{"internalType":"enum PerpV2LeverageStrategyExtension.ShouldRebalance","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"twapLeverageRatio","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"_status","type":"bool"}],"name":"updateAnyoneCallable","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_callers","type":"address[]"},{"internalType":"bool[]","name":"_statuses","type":"bool[]"}],"name":"updateCallerStatus","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_collateralUnits","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawEtherBalance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}] | |
const strategyExtensionAddress = "0xPERP_STRATEGY_ADDRESS"; | |
exports.handler = async function(credentials) { | |
const relayer = new Relayer(credentials); | |
const pendingTransactions = await relayer.list({ | |
since: new Date(Date.now() - 60 * 60 * 24), | |
status: 'pending', | |
limit: 5, | |
}); | |
// If tx is pending do not resend. Defender will auto bump the pending txs price until it is included. | |
if (pendingTransactions.length > 0) { | |
return -1; | |
} | |
const provider = new DefenderRelayProvider(credentials); | |
const signer = new DefenderRelaySigner(credentials, provider, { speed: 'fast' }); | |
return rebalance(signer, strategyExtensionAddress); | |
} | |
const rebalance = async (signer, strategyExtensionAddress) => { | |
const strategyExtension = new ethers.Contract(strategyExtensionAddress, abi, signer); | |
const [exchangeNames, rebalEnums] = await strategyExtension.shouldRebalanceWithBounds( | |
ethers.utils.parseEther("1.7"), | |
ethers.utils.parseEther("2.3") | |
); | |
if (shouldRebalance === 1) { | |
const tx = await strategyExtension.rebalance({ gasLimit: 1000000}); | |
return tx; | |
} else if (shouldRebalance === 2) { | |
const tx = await strategyExtension.iterateRebalance({ gasLimit: 1000000}); | |
return tx; | |
} else if (shouldRebalance === 3) { | |
const tx = await strategyExtension.ripcord({ gasLimit: 1000000}); | |
return tx; | |
} | |
return shouldRebalance; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment