Example 2 (#28)
* Set up contracts for second example (#8)
Co-authored-by: gator-boi <gator-boi@users.noreply.github.com>
* Set up contract state (#11)
* Set up contracts for second example
* Delete README
* Define interface and contract state
Co-authored-by: gator-boi <gator-boi@users.noreply.github.com>
* Hub messages (#12)
* Update HubMessages.sol
* Update HubStructs.sol
* finish decode msgs (#13)
* Update HubMessages.sol
* Update HubStructs.sol
* write decode messages
Co-authored-by: derpy-duck <115193320+derpy-duck@users.noreply.github.com>
* Add .vscode to gitignore (#14)
Co-authored-by: derpy-duck <akadaveru@guse4c-ossdev-akl1.jumpisolated.com>
* Fixing some compile errors in HubMessages (#15)
* Fixing some compile errors in HubMessages
* Add Register Spoke method to register spokes on hub
* Implement completeRegisterSpoke
* Add chainId to message header, and add a check function to ensure the spoke that a message comes from is registered
* Add getWormholePayload function
* Remove registerSpoke as a wormhole message, and only allow on the hub as owner
Co-authored-by: derpy-duck <akadaveru@guse4c-ossdev-akl1.jumpisolated.com>
* Test files (#16)
* Fixing some compile errors in HubMessages
* Basic test
Co-authored-by: derpy-duck <akadaveru@guse4c-ossdev-akl1.jumpisolated.com>
* first pass at lending Hub completeDeposit (#17)
* first pass at lending Hub completeDeposit
* added barebones logic to completeWithdraw
* add some skeleton for repay & liquidation
* added some comments
* Progress 12:30-1:30
* forge install: forge-std
* fixed errors
* derpy-ducks's fixes
Co-authored-by: wrinkled-latherer
Co-authored-by: derpy-duck <115193320+derpy-duck@users.noreply.github.com>
* Adding encoding and decoding payload tests (#20)
* Derpy duck refactor and borrow (#21)
* Borrow
* transfer tokens empty function
* sign fix
* added collateralization ratio precision
* Liquidation and register msg (#19)
* mock Pyth
* shot myself in the foot
* tried fixing comment
* test
* set vault and global amounts
Co-authored-by: wrinkled-latherer <114771197+wrinkledLatherer@users.noreply.github.com>
Co-authored-by: derpy-duck <115193320+derpy-duck@users.noreply.github.com>
* cleanup (#22)
* Reorganized into HubUtilities and added docstrings to HubUtilities (#23)
* Reorganized into HubUtilities and added docstrings to HubUtilities
* Move the helper functions from Hub into HubUtilities
* Adding back a TODO
* Hub docstrings (#25)
* Hub specs
* Fixed allowedToWithdraw to add another check of making sure that there is enough total supply in the protocol before going ahead with a withdrawal
* Writing hub tests (#26)
* dump of testing
* makefile
* evm: fix token transfer encoding
* fixed slice issues, deposit test working
* tad
* refactored testing code to be cleaner
* updated tests with index accrual precision updated
* Seperated tests into helper file and main file
* enable manual oracle setting
* begin borrow testing
* Borrow test passes!
* resolved some todos
* addressed low decimals exploit
* add comment
Co-authored-by: wrinkledLatherer
Co-authored-by: A5 Pickle <a5-pickle@users.noreply.github.com>
* Test updates (#27)
* Fix compile error
* Max decimals
* test updates
* Changing the tests that fail to fail tests
* Cleaning up price code in tests
* CLEAN testing file!
* Removing some redundant comments
* Repay tests
* make decimals part of adaptive state
* added some comments
* fixed max liquidation bonus setting
* fix liquidation test
Co-authored-by: wrinkledLatherer
* Spoke (#24)
* Implementation of spoke methods without tokenbridge
* Added token bridge portion
* Implementation of spoke methods without tokenbridge
* Added token bridge portion
* Remove merge conflict
* Check valid address
* Swap token bridge payload to wormhole payload
* Lending detail (#29)
* add interest rate model params to asset info
* add liquidation max portion repayable as param
* add reserve factor usage
* add multiple collat ratios
* figure out some todos
Co-authored-by: wrinkledLatherer <asuresh@dub2t-btcdevl1.w2k.jumptrading.com>
* Derpy duck changes (#30)
* Move functions from Spoke to SpokeUtilities
* Fix address we are signing wormhole message with, and add a 'check duplicates' function for asset arrays passed into liquidation
* Token transfers (#31)
* implement transferTokens function
* Approve token transfers and fix compile errors
* Token transfers more
* Testing prank mint (#32)
* Testing prank mint
* Remove changes to MyERC20
* fixed fake minting
* Changed hardcoded addresses to refer to asset[0] and asset[1], and also changed testFail to use vm.expectRevert
Co-authored-by: wrinkledLatherer
* First integration test (#33)
* Real oracle (#34)
* Mock Pyth working
* add confidence computation to price
* add pyth docs link in comments
* made nConf intervals a param
* consolidated diff oracleMode update price feed fns into one fn
Co-authored-by: wrinkledLatherer
* Cleaned up price calls (#36)
* More integration tests (#35)
* Slight cleaning of first integration test
* some fixes
* attempt token bridge integration test deposit
* Working deposit testgit add .git add .!
* Nicer hub only tests
* Fix compile errors
* initialize publishtime
* remove comments
* Decimals (#37)
* decimal overflow error huh
* pushed some console msgs
* tests pass!
* put division at the end for rounding reasons
Co-authored-by: wrinkledLatherer <asuresh@dub2t-btcdevl1.w2k.jumptrading.com>
* Cleaning integration tests (#39)
* add the integration tests
* Reorganization of test file progress
* Testing files giant reorg
* Combine deposit repay withdraw borrow test methods
* Integration tests pass!
* Remove completeRegisterAsset and all asset state on spoke
* requires in the test methods
* Verify sender is spoke for token bridge messages
* lint fixes (#40)
* Prettier formatting, and normalize hub amounts in test before checking validity (#41)
* Native token transfer (#38)
* add initial native token tfer tests
* add WETH interface
* got native token tfer working
* added tests for repay native
* added reversion for repayments
* get rid of some unnecessary TODOs
* Repay check
* testRDBL passes; removed some redundant requires
Co-authored-by: wrinkledLatherer <wrinkledLatherer>
Co-authored-by: derpy-duck <115193320+derpy-duck@users.noreply.github.com>
* Derpy duck testing improvements (#44)
* doLiquidate and liquidation checks
* move nativeeth requires into helper method, and combine doAction and doActionNative
* AddAsset struct around adding assets
* Move set price to helper function
* Combine test methods with their fail counterparts
* liquidation additional require statement about global supply
* Hub spoke cleanup combining methods (#45)
* Remove unnecessary variables
* Combine deposit borrow withdraw and repay structs and methods on hub; prevents relayer from choosing which functions to relay message to
* Remove unused test utility files related to creating signed WH messages for testing purposes
* Remove unnecessary spoke methods setters adn getters
* Remove unnecessary spoke imports
* Far cleaner Hub file
* Generalize HubMessages and HubStructs, and account for dust in Hub logging (#46)
* Remove transfer result struct (#47)
* Generalize HubMessages and HubStructs, and account for dust in Hub logging
* remove one struct
* remove one struct
* Hub specs (#48)
* Remove unnecessary test method
* Rename nConf to priceStandardDeviations
* Specs
* fix parse error
* subtract messageFee from amount when doing check
* Careful thinking about divisions as it relates to interest rates (#49)
* More specs (#50)
* More specs
* Add price specs
* prettier formatting
* docstring fix
* Successful interest rate and price conf tests (#52)
* Spoke spec for constructor
* Correct typo in spec
* Tidying and interest rate additions (#54)
* tidy up checks in completeAction on hub
* add some documentation around the double round up in allowedToRepay
* add piecewise linear interest rate model
* remove rate intercept and rate coefficient
* add checks for kinks and rates to be valid
* Test helper fix (#53)
* Consider dust in test, and use public getters or acocunt balances (#55)
* evm: fix yarn.lock
* evm: fix guardian set index
* evm: fix Makefile
* evm: fix stack too deep
* evm: fix README
* evm: remove lib/forge-std
Co-authored-by: Reptile <43194093+gator-boi@users.noreply.github.com>
Co-authored-by: gator-boi <gator-boi@users.noreply.github.com>
Co-authored-by: wrinkledLatherer <114771197+wrinkledLatherer@users.noreply.github.com>
Co-authored-by: derpy-duck <akadaveru@guse4c-ossdev-akl1.jumpisolated.com>
Co-authored-by: A5 Pickle <a5-pickle@users.noreply.github.com>
Co-authored-by: wrinkledLatherer <asuresh@dub2t-btcdevl1.w2k.jumptrading.com>
2023-01-25 10:12:07 -08:00
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^ 0 . 8 . 0 ;
import " ../HubSpokeStructs.sol " ;
import " ./HubGetters.sol " ;
import " ./HubSetters.sol " ;
contract HubInterestUtilities is HubSpokeStructs , HubGetters , HubSetters {
/*
*
* The following three functions describe the Interest Rate Model of the whole protocol !
* TODO : IMPORTANT ! Substitute this function out for whatever desired interest rate model you wish to have
*
* /
/**
* @ notice Assets accrue interest over time , so at any given point in time the value of an asset is ( amount of asset on day 1 ) * ( the amount of interest that has accrued ) .
* This function updates both the deposit and borrow interest accrual indices of the asset .
*
* @ param assetAddress - The asset to update the interest accrual indices of
* /
function updateAccrualIndices ( address assetAddress ) internal {
setInterestAccrualIndices ( assetAddress , getCurrentAccrualIndices ( assetAddress ) ) ;
setLastActivityBlockTimestamp ( assetAddress , block . timestamp ) ;
}
function getCurrentAccrualIndices ( address assetAddress ) internal view returns ( AccrualIndices memory ) {
uint256 lastActivityBlockTimestamp = getLastActivityBlockTimestamp ( assetAddress ) ;
uint256 secondsElapsed = block . timestamp - lastActivityBlockTimestamp ;
uint256 deposited = getTotalAssetsDeposited ( assetAddress ) ;
AccrualIndices memory accrualIndices = getInterestAccrualIndices ( assetAddress ) ;
if ( ( secondsElapsed != 0 ) && ( deposited != 0 ) ) {
uint256 borrowed = getTotalAssetsBorrowed ( assetAddress ) ;
PiecewiseInterestRateModel memory interestRateModel = getInterestRateModel ( assetAddress ) ;
uint256 interestFactor = computeSourceInterestFactor ( secondsElapsed , deposited , borrowed , interestRateModel ) ;
AssetInfo memory assetInfo = getAssetInfo ( assetAddress ) ;
uint256 reserveFactor = assetInfo . interestRateModel . reserveFactor ;
uint256 reservePrecision = assetInfo . interestRateModel . reservePrecision ;
accrualIndices . borrowed += interestFactor ;
accrualIndices . deposited +=
( interestFactor * ( reservePrecision - reserveFactor ) * borrowed ) / reservePrecision / deposited ;
}
return accrualIndices ;
}
function computeSourceInterestFactor (
uint256 secondsElapsed ,
uint256 deposited ,
uint256 borrowed ,
PiecewiseInterestRateModel memory interestRateModel
) internal view returns ( uint256 ) {
if ( deposited == 0 ) {
return 0 ;
}
uint256 [ ] memory kinks = interestRateModel . kinks ;
uint256 [ ] memory rates = interestRateModel . rates ;
uint i = 0 ;
uint256 interestRate = 0 ;
while ( borrowed * interestRateModel . ratePrecision > deposited * kinks [ i ] ) {
interestRate = rates [ i ] ;
i += 1 ;
if ( i == rates . length ) {
return rates [ i - 1 ] ;
}
}
// if zero borrows and nonzero deposits, then set interest rate for period to the rate intercept i.e. first kink; ow linearly interpolate between kinks
if ( i == 0 ) {
interestRate = rates [ 0 ] ;
}
else {
2023-01-26 11:30:16 -08:00
interestRate += ( rates [ i ] - rates [ i - 1 ] ) * ( ( borrowed * interestRateModel . ratePrecision - kinks [ i - 1 ] * deposited ) / deposited ) / ( kinks [ i ] - kinks [ i - 1 ] ) ;
Example 2 (#28)
* Set up contracts for second example (#8)
Co-authored-by: gator-boi <gator-boi@users.noreply.github.com>
* Set up contract state (#11)
* Set up contracts for second example
* Delete README
* Define interface and contract state
Co-authored-by: gator-boi <gator-boi@users.noreply.github.com>
* Hub messages (#12)
* Update HubMessages.sol
* Update HubStructs.sol
* finish decode msgs (#13)
* Update HubMessages.sol
* Update HubStructs.sol
* write decode messages
Co-authored-by: derpy-duck <115193320+derpy-duck@users.noreply.github.com>
* Add .vscode to gitignore (#14)
Co-authored-by: derpy-duck <akadaveru@guse4c-ossdev-akl1.jumpisolated.com>
* Fixing some compile errors in HubMessages (#15)
* Fixing some compile errors in HubMessages
* Add Register Spoke method to register spokes on hub
* Implement completeRegisterSpoke
* Add chainId to message header, and add a check function to ensure the spoke that a message comes from is registered
* Add getWormholePayload function
* Remove registerSpoke as a wormhole message, and only allow on the hub as owner
Co-authored-by: derpy-duck <akadaveru@guse4c-ossdev-akl1.jumpisolated.com>
* Test files (#16)
* Fixing some compile errors in HubMessages
* Basic test
Co-authored-by: derpy-duck <akadaveru@guse4c-ossdev-akl1.jumpisolated.com>
* first pass at lending Hub completeDeposit (#17)
* first pass at lending Hub completeDeposit
* added barebones logic to completeWithdraw
* add some skeleton for repay & liquidation
* added some comments
* Progress 12:30-1:30
* forge install: forge-std
* fixed errors
* derpy-ducks's fixes
Co-authored-by: wrinkled-latherer
Co-authored-by: derpy-duck <115193320+derpy-duck@users.noreply.github.com>
* Adding encoding and decoding payload tests (#20)
* Derpy duck refactor and borrow (#21)
* Borrow
* transfer tokens empty function
* sign fix
* added collateralization ratio precision
* Liquidation and register msg (#19)
* mock Pyth
* shot myself in the foot
* tried fixing comment
* test
* set vault and global amounts
Co-authored-by: wrinkled-latherer <114771197+wrinkledLatherer@users.noreply.github.com>
Co-authored-by: derpy-duck <115193320+derpy-duck@users.noreply.github.com>
* cleanup (#22)
* Reorganized into HubUtilities and added docstrings to HubUtilities (#23)
* Reorganized into HubUtilities and added docstrings to HubUtilities
* Move the helper functions from Hub into HubUtilities
* Adding back a TODO
* Hub docstrings (#25)
* Hub specs
* Fixed allowedToWithdraw to add another check of making sure that there is enough total supply in the protocol before going ahead with a withdrawal
* Writing hub tests (#26)
* dump of testing
* makefile
* evm: fix token transfer encoding
* fixed slice issues, deposit test working
* tad
* refactored testing code to be cleaner
* updated tests with index accrual precision updated
* Seperated tests into helper file and main file
* enable manual oracle setting
* begin borrow testing
* Borrow test passes!
* resolved some todos
* addressed low decimals exploit
* add comment
Co-authored-by: wrinkledLatherer
Co-authored-by: A5 Pickle <a5-pickle@users.noreply.github.com>
* Test updates (#27)
* Fix compile error
* Max decimals
* test updates
* Changing the tests that fail to fail tests
* Cleaning up price code in tests
* CLEAN testing file!
* Removing some redundant comments
* Repay tests
* make decimals part of adaptive state
* added some comments
* fixed max liquidation bonus setting
* fix liquidation test
Co-authored-by: wrinkledLatherer
* Spoke (#24)
* Implementation of spoke methods without tokenbridge
* Added token bridge portion
* Implementation of spoke methods without tokenbridge
* Added token bridge portion
* Remove merge conflict
* Check valid address
* Swap token bridge payload to wormhole payload
* Lending detail (#29)
* add interest rate model params to asset info
* add liquidation max portion repayable as param
* add reserve factor usage
* add multiple collat ratios
* figure out some todos
Co-authored-by: wrinkledLatherer <asuresh@dub2t-btcdevl1.w2k.jumptrading.com>
* Derpy duck changes (#30)
* Move functions from Spoke to SpokeUtilities
* Fix address we are signing wormhole message with, and add a 'check duplicates' function for asset arrays passed into liquidation
* Token transfers (#31)
* implement transferTokens function
* Approve token transfers and fix compile errors
* Token transfers more
* Testing prank mint (#32)
* Testing prank mint
* Remove changes to MyERC20
* fixed fake minting
* Changed hardcoded addresses to refer to asset[0] and asset[1], and also changed testFail to use vm.expectRevert
Co-authored-by: wrinkledLatherer
* First integration test (#33)
* Real oracle (#34)
* Mock Pyth working
* add confidence computation to price
* add pyth docs link in comments
* made nConf intervals a param
* consolidated diff oracleMode update price feed fns into one fn
Co-authored-by: wrinkledLatherer
* Cleaned up price calls (#36)
* More integration tests (#35)
* Slight cleaning of first integration test
* some fixes
* attempt token bridge integration test deposit
* Working deposit testgit add .git add .!
* Nicer hub only tests
* Fix compile errors
* initialize publishtime
* remove comments
* Decimals (#37)
* decimal overflow error huh
* pushed some console msgs
* tests pass!
* put division at the end for rounding reasons
Co-authored-by: wrinkledLatherer <asuresh@dub2t-btcdevl1.w2k.jumptrading.com>
* Cleaning integration tests (#39)
* add the integration tests
* Reorganization of test file progress
* Testing files giant reorg
* Combine deposit repay withdraw borrow test methods
* Integration tests pass!
* Remove completeRegisterAsset and all asset state on spoke
* requires in the test methods
* Verify sender is spoke for token bridge messages
* lint fixes (#40)
* Prettier formatting, and normalize hub amounts in test before checking validity (#41)
* Native token transfer (#38)
* add initial native token tfer tests
* add WETH interface
* got native token tfer working
* added tests for repay native
* added reversion for repayments
* get rid of some unnecessary TODOs
* Repay check
* testRDBL passes; removed some redundant requires
Co-authored-by: wrinkledLatherer <wrinkledLatherer>
Co-authored-by: derpy-duck <115193320+derpy-duck@users.noreply.github.com>
* Derpy duck testing improvements (#44)
* doLiquidate and liquidation checks
* move nativeeth requires into helper method, and combine doAction and doActionNative
* AddAsset struct around adding assets
* Move set price to helper function
* Combine test methods with their fail counterparts
* liquidation additional require statement about global supply
* Hub spoke cleanup combining methods (#45)
* Remove unnecessary variables
* Combine deposit borrow withdraw and repay structs and methods on hub; prevents relayer from choosing which functions to relay message to
* Remove unused test utility files related to creating signed WH messages for testing purposes
* Remove unnecessary spoke methods setters adn getters
* Remove unnecessary spoke imports
* Far cleaner Hub file
* Generalize HubMessages and HubStructs, and account for dust in Hub logging (#46)
* Remove transfer result struct (#47)
* Generalize HubMessages and HubStructs, and account for dust in Hub logging
* remove one struct
* remove one struct
* Hub specs (#48)
* Remove unnecessary test method
* Rename nConf to priceStandardDeviations
* Specs
* fix parse error
* subtract messageFee from amount when doing check
* Careful thinking about divisions as it relates to interest rates (#49)
* More specs (#50)
* More specs
* Add price specs
* prettier formatting
* docstring fix
* Successful interest rate and price conf tests (#52)
* Spoke spec for constructor
* Correct typo in spec
* Tidying and interest rate additions (#54)
* tidy up checks in completeAction on hub
* add some documentation around the double round up in allowedToRepay
* add piecewise linear interest rate model
* remove rate intercept and rate coefficient
* add checks for kinks and rates to be valid
* Test helper fix (#53)
* Consider dust in test, and use public getters or acocunt balances (#55)
* evm: fix yarn.lock
* evm: fix guardian set index
* evm: fix Makefile
* evm: fix stack too deep
* evm: fix README
* evm: remove lib/forge-std
Co-authored-by: Reptile <43194093+gator-boi@users.noreply.github.com>
Co-authored-by: gator-boi <gator-boi@users.noreply.github.com>
Co-authored-by: wrinkledLatherer <114771197+wrinkledLatherer@users.noreply.github.com>
Co-authored-by: derpy-duck <akadaveru@guse4c-ossdev-akl1.jumpisolated.com>
Co-authored-by: A5 Pickle <a5-pickle@users.noreply.github.com>
Co-authored-by: wrinkledLatherer <asuresh@dub2t-btcdevl1.w2k.jumptrading.com>
2023-01-25 10:12:07 -08:00
}
return ( getInterestAccrualIndexPrecision ( ) * secondsElapsed * interestRate / interestRateModel . ratePrecision ) / 365 / 24 / 60 / 60 ;
}
/*
*
* End Interest Rate Model
*
* /
/**
* @ notice Assets accrue interest over time , so at any given point in time the value of an asset is ( amount of asset on day 1 ) * ( the amount of interest that has accrued ) .
*
* @ param denormalizedAmount - The true amount of an asset
* @ param interestAccrualIndex - The amount of interest that has accrued , multiplied by getInterestAccrualIndexPrecision ( ) .
* So , ( interestAccrualIndex / interestAccrualIndexPrecision ) represents the interest accrued ( this is initialized to 1 at the start of the protocol )
* @ return { uint256 } The normalized amount of the asset
* /
function normalizeAmount ( uint256 denormalizedAmount , uint256 interestAccrualIndex , Round round )
public
view
returns ( uint256 )
{
return divide ( denormalizedAmount * getInterestAccrualIndexPrecision ( ) , interestAccrualIndex , round ) ;
}
/**
* @ notice Similar to ' normalizeAmount ' , takes a normalized value ( amount of an asset ) and denormalizes it .
*
* @ param normalizedAmount - The normalized amount of an asset
* @ param interestAccrualIndex - The amount of interest that has accrued , multiplied by getInterestAccrualIndexPrecision ( ) .
* @ return { uint256 } The true amount of the asset
* /
function denormalizeAmount ( uint256 normalizedAmount , uint256 interestAccrualIndex , Round round )
public
view
returns ( uint256 )
{
return divide ( normalizedAmount * interestAccrualIndex , getInterestAccrualIndexPrecision ( ) , round ) ;
}
/**
* @ notice Get a user ' s account balance in an asset
*
* @ param vaultOwner - the address of the user
* @ param assetAddress - the address of the asset
* @ return a struct with ' deposited ' field and ' borrowed ' field for the amount deposited and borrowed of the asset
* multiplied by 10 ^ decimal for that asset . Values are denormalized .
* /
function getUserBalance ( address vaultOwner , address assetAddress ) public view returns ( VaultAmount memory ) {
VaultAmount memory normalized = getVaultAmounts ( vaultOwner , assetAddress ) ;
AccrualIndices memory interestAccrualIndex = getCurrentAccrualIndices ( assetAddress ) ;
return VaultAmount ( {
deposited : denormalizeAmount ( normalized . deposited , interestAccrualIndex . deposited , Round . DOWN ) ,
borrowed : denormalizeAmount ( normalized . borrowed , interestAccrualIndex . borrowed , Round . UP )
} ) ;
}
/**
* @ notice Get the protocol ' s global balance in an asset
*
* @ param assetAddress - the address of the asset
* @ return a struct with ' deposited ' field and ' borrowed ' field for the amount deposited and borrowed of the asset
* multiplied by 10 ^ decimal for that asset . Values are denormalized .
* /
function getGlobalBalance ( address assetAddress ) public view returns ( VaultAmount memory ) {
VaultAmount memory normalized = getGlobalAmounts ( assetAddress ) ;
AccrualIndices memory interestAccrualIndex = getCurrentAccrualIndices ( assetAddress ) ;
return VaultAmount ( {
deposited : denormalizeAmount ( normalized . deposited , interestAccrualIndex . deposited , Round . DOWN ) ,
borrowed : denormalizeAmount ( normalized . borrowed , interestAccrualIndex . borrowed , Round . UP )
} ) ;
}
/**
* @ notice Divide helper function , for rounding
*
* @ param dividend - the dividend
* @ param divisor - the divisor
* @ param round - Whether or not to round up ( Round . UP ) or round down ( Round . DOWN )
* @ return dividend / divisor , rounded appropriately
* /
function divide ( uint256 dividend , uint256 divisor , Round round ) internal pure returns ( uint256 ) {
uint256 modulo = dividend % divisor ;
uint256 quotient = dividend / divisor ;
if ( modulo == 0 || round == Round . DOWN ) {
return quotient ;
}
return quotient + 1 ;
}
}