-
Notifications
You must be signed in to change notification settings - Fork 48
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
490 additions
and
36 deletions.
There are no files selected for viewing
206 changes: 206 additions & 0 deletions
206
external/abi/set/BoundedStepwiseLinearPriceAdapter.json
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,206 @@ | ||
{ | ||
"_format": "hh-sol-artifact-1", | ||
"contractName": "BoundedStepwiseLinearPriceAdapter", | ||
"sourceName": "contracts/protocol/integration/auction-price/BoundedStepwiseLinearPriceAdapter.sol", | ||
"abi": [ | ||
{ | ||
"inputs": [ | ||
{ | ||
"internalType": "uint256", | ||
"name": "_initialPrice", | ||
"type": "uint256" | ||
}, | ||
{ | ||
"internalType": "uint256", | ||
"name": "_slope", | ||
"type": "uint256" | ||
}, | ||
{ | ||
"internalType": "uint256", | ||
"name": "_bucketSize", | ||
"type": "uint256" | ||
}, | ||
{ | ||
"internalType": "uint256", | ||
"name": "_maxPrice", | ||
"type": "uint256" | ||
}, | ||
{ | ||
"internalType": "uint256", | ||
"name": "_minPrice", | ||
"type": "uint256" | ||
} | ||
], | ||
"name": "areParamsValid", | ||
"outputs": [ | ||
{ | ||
"internalType": "bool", | ||
"name": "", | ||
"type": "bool" | ||
} | ||
], | ||
"stateMutability": "pure", | ||
"type": "function", | ||
"gas": "0xa7d8c0" | ||
}, | ||
{ | ||
"inputs": [ | ||
{ | ||
"internalType": "bytes", | ||
"name": "_data", | ||
"type": "bytes" | ||
} | ||
], | ||
"name": "getDecodedData", | ||
"outputs": [ | ||
{ | ||
"internalType": "uint256", | ||
"name": "initialPrice", | ||
"type": "uint256" | ||
}, | ||
{ | ||
"internalType": "uint256", | ||
"name": "slope", | ||
"type": "uint256" | ||
}, | ||
{ | ||
"internalType": "uint256", | ||
"name": "bucketSize", | ||
"type": "uint256" | ||
}, | ||
{ | ||
"internalType": "bool", | ||
"name": "isDecreasing", | ||
"type": "bool" | ||
}, | ||
{ | ||
"internalType": "uint256", | ||
"name": "maxPrice", | ||
"type": "uint256" | ||
}, | ||
{ | ||
"internalType": "uint256", | ||
"name": "minPrice", | ||
"type": "uint256" | ||
} | ||
], | ||
"stateMutability": "pure", | ||
"type": "function", | ||
"gas": "0xa7d8c0" | ||
}, | ||
{ | ||
"inputs": [ | ||
{ | ||
"internalType": "uint256", | ||
"name": "_initialPrice", | ||
"type": "uint256" | ||
}, | ||
{ | ||
"internalType": "uint256", | ||
"name": "_slope", | ||
"type": "uint256" | ||
}, | ||
{ | ||
"internalType": "uint256", | ||
"name": "_bucketSize", | ||
"type": "uint256" | ||
}, | ||
{ | ||
"internalType": "bool", | ||
"name": "_isDecreasing", | ||
"type": "bool" | ||
}, | ||
{ | ||
"internalType": "uint256", | ||
"name": "_maxPrice", | ||
"type": "uint256" | ||
}, | ||
{ | ||
"internalType": "uint256", | ||
"name": "_minPrice", | ||
"type": "uint256" | ||
} | ||
], | ||
"name": "getEncodedData", | ||
"outputs": [ | ||
{ | ||
"internalType": "bytes", | ||
"name": "data", | ||
"type": "bytes" | ||
} | ||
], | ||
"stateMutability": "pure", | ||
"type": "function", | ||
"gas": "0xa7d8c0" | ||
}, | ||
{ | ||
"inputs": [ | ||
{ | ||
"internalType": "address", | ||
"name": "", | ||
"type": "address" | ||
}, | ||
{ | ||
"internalType": "address", | ||
"name": "", | ||
"type": "address" | ||
}, | ||
{ | ||
"internalType": "uint256", | ||
"name": "", | ||
"type": "uint256" | ||
}, | ||
{ | ||
"internalType": "uint256", | ||
"name": "_timeElapsed", | ||
"type": "uint256" | ||
}, | ||
{ | ||
"internalType": "uint256", | ||
"name": "", | ||
"type": "uint256" | ||
}, | ||
{ | ||
"internalType": "bytes", | ||
"name": "_priceAdapterConfigData", | ||
"type": "bytes" | ||
} | ||
], | ||
"name": "getPrice", | ||
"outputs": [ | ||
{ | ||
"internalType": "uint256", | ||
"name": "price", | ||
"type": "uint256" | ||
} | ||
], | ||
"stateMutability": "pure", | ||
"type": "function", | ||
"gas": "0xa7d8c0" | ||
}, | ||
{ | ||
"inputs": [ | ||
{ | ||
"internalType": "bytes", | ||
"name": "_priceAdapterConfigData", | ||
"type": "bytes" | ||
} | ||
], | ||
"name": "isPriceAdapterConfigDataValid", | ||
"outputs": [ | ||
{ | ||
"internalType": "bool", | ||
"name": "isValid", | ||
"type": "bool" | ||
} | ||
], | ||
"stateMutability": "pure", | ||
"type": "function", | ||
"gas": "0xa7d8c0" | ||
} | ||
], | ||
"bytecode": "0x608060405234801561001057600080fd5b506106d0806100206000396000f3fe608060405234801561001057600080fd5b50600436106100575760003560e01c8063079f6bf41461005c578063104b9b641461008457806363dc2e6b146100a5578063bf160e2514610105578063d3516db614610118575b600080fd5b61006f61006a36600461040a565b61015a565b60405190151581526020015b60405180910390f35b610097610092366004610463565b61018f565b60405190815260200161007b565b6100f86100b33660046104ee565b604080516020810197909752868101959095526060860193909352901515608085015260a084015260c0808401919091528151808403909101815260e0909201905290565b60405161007b9190610541565b61006f61011336600461058f565b6102fa565b61012b61012636600461040a565b610336565b6040805196875260208701959095529385019290925215156060840152608083015260a082015260c00161007b565b60008060008060008061016c87610336565b955095505094509450945061018485858585856102fa565b979650505050505050565b60008060008060008060006101a388610336565b9550955095509550955095506101bc86868685856102fa565b6102265760405162461bcd60e51b815260206004820152603160248201527f426f756e64656453746570776973654c696e6561725072696365416461707465604482015270723a20496e76616c696420706172616d7360781b606482015260840160405180910390fd5b6000610232858c6105e0565b9050610240866000196105e0565b81111561026257836102525782610254565b815b9750505050505050506102f0565b600061026e8783610602565b905084156102b5578781111561028e5782985050505050505050506102f0565b6102a661029b828a61061f565b848110818618021890565b985050505050505050506102f0565b6102c18860001961061f565b8111156102d85783985050505050505050506102f0565b6102a66102e5828a610632565b858111818718021890565b9695505050505050565b6000808611801561030b5750600085115b80156103175750600084115b80156103235750828611155b80156102f0575050909310159392505050565b600080600080600080868060200190518101906103539190610645565b949c939b5091995097509550909350915050565b634e487b7160e01b600052604160045260246000fd5b600082601f83011261038e57600080fd5b813567ffffffffffffffff808211156103a9576103a9610367565b604051601f8301601f19908116603f011681019082821181831017156103d1576103d1610367565b816040528381528660208588010111156103ea57600080fd5b836020870160208301376000602085830101528094505050505092915050565b60006020828403121561041c57600080fd5b813567ffffffffffffffff81111561043357600080fd5b61043f8482850161037d565b949350505050565b80356001600160a01b038116811461045e57600080fd5b919050565b60008060008060008060c0878903121561047c57600080fd5b61048587610447565b955061049360208801610447565b945060408701359350606087013592506080870135915060a087013567ffffffffffffffff8111156104c457600080fd5b6104d089828a0161037d565b9150509295509295509295565b80151581146104eb57600080fd5b50565b60008060008060008060c0878903121561050757600080fd5b8635955060208701359450604087013593506060870135610527816104dd565b9598949750929560808101359460a0909101359350915050565b600060208083528351808285015260005b8181101561056e57858101830151858201604001528201610552565b506000604082860101526040601f19601f8301168501019250505092915050565b600080600080600060a086880312156105a757600080fd5b505083359560208501359550604085013594606081013594506080013592509050565b634e487b7160e01b600052601160045260246000fd5b6000826105fd57634e487b7160e01b600052601260045260246000fd5b500490565b8082028115828204841417610619576106196105ca565b92915050565b81810381811115610619576106196105ca565b80820180821115610619576106196105ca565b60008060008060008060c0878903121561065e57600080fd5b865195506020870151945060408701519350606087015161067e816104dd565b809350506080870151915060a08701519050929550929550929556fea2646970667358221220a50447f4d241ad3f0e8ac061ae0c04c474f1f7c3a7a5cab954e568dac556890e64736f6c63430008110033", | ||
"deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100575760003560e01c8063079f6bf41461005c578063104b9b641461008457806363dc2e6b146100a5578063bf160e2514610105578063d3516db614610118575b600080fd5b61006f61006a36600461040a565b61015a565b60405190151581526020015b60405180910390f35b610097610092366004610463565b61018f565b60405190815260200161007b565b6100f86100b33660046104ee565b604080516020810197909752868101959095526060860193909352901515608085015260a084015260c0808401919091528151808403909101815260e0909201905290565b60405161007b9190610541565b61006f61011336600461058f565b6102fa565b61012b61012636600461040a565b610336565b6040805196875260208701959095529385019290925215156060840152608083015260a082015260c00161007b565b60008060008060008061016c87610336565b955095505094509450945061018485858585856102fa565b979650505050505050565b60008060008060008060006101a388610336565b9550955095509550955095506101bc86868685856102fa565b6102265760405162461bcd60e51b815260206004820152603160248201527f426f756e64656453746570776973654c696e6561725072696365416461707465604482015270723a20496e76616c696420706172616d7360781b606482015260840160405180910390fd5b6000610232858c6105e0565b9050610240866000196105e0565b81111561026257836102525782610254565b815b9750505050505050506102f0565b600061026e8783610602565b905084156102b5578781111561028e5782985050505050505050506102f0565b6102a661029b828a61061f565b848110818618021890565b985050505050505050506102f0565b6102c18860001961061f565b8111156102d85783985050505050505050506102f0565b6102a66102e5828a610632565b858111818718021890565b9695505050505050565b6000808611801561030b5750600085115b80156103175750600084115b80156103235750828611155b80156102f0575050909310159392505050565b600080600080600080868060200190518101906103539190610645565b949c939b5091995097509550909350915050565b634e487b7160e01b600052604160045260246000fd5b600082601f83011261038e57600080fd5b813567ffffffffffffffff808211156103a9576103a9610367565b604051601f8301601f19908116603f011681019082821181831017156103d1576103d1610367565b816040528381528660208588010111156103ea57600080fd5b836020870160208301376000602085830101528094505050505092915050565b60006020828403121561041c57600080fd5b813567ffffffffffffffff81111561043357600080fd5b61043f8482850161037d565b949350505050565b80356001600160a01b038116811461045e57600080fd5b919050565b60008060008060008060c0878903121561047c57600080fd5b61048587610447565b955061049360208801610447565b945060408701359350606087013592506080870135915060a087013567ffffffffffffffff8111156104c457600080fd5b6104d089828a0161037d565b9150509295509295509295565b80151581146104eb57600080fd5b50565b60008060008060008060c0878903121561050757600080fd5b8635955060208701359450604087013593506060870135610527816104dd565b9598949750929560808101359460a0909101359350915050565b600060208083528351808285015260005b8181101561056e57858101830151858201604001528201610552565b506000604082860101526040601f19601f8301168501019250505092915050565b600080600080600060a086880312156105a757600080fd5b505083359560208501359550604085013594606081013594506080013592509050565b634e487b7160e01b600052601160045260246000fd5b6000826105fd57634e487b7160e01b600052601260045260246000fd5b500490565b8082028115828204841417610619576106196105ca565b92915050565b81810381811115610619576106196105ca565b80820180821115610619576106196105ca565b60008060008060008060c0878903121561065e57600080fd5b865195506020870151945060408701519350606087015161067e816104dd565b809350506080870151915060a08701519050929550929550929556fea2646970667358221220a50447f4d241ad3f0e8ac061ae0c04c474f1f7c3a7a5cab954e568dac556890e64736f6c63430008110033", | ||
"linkReferences": {}, | ||
"deployedLinkReferences": {} | ||
} |
169 changes: 169 additions & 0 deletions
169
external/contracts/set/BoundedStepwiseLinearPriceAdapter.sol
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,169 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
pragma solidity 0.8.17; | ||
|
||
import { FixedPointMathLib } from "solady/src/utils/FixedPointMathLib.sol"; | ||
|
||
/** | ||
* @title BoundedStepwiseLinearPriceAdapter | ||
* @author Index Coop | ||
* @notice Price adapter contract for the AuctionRebalanceModuleV1. It returns a price that | ||
* increases or decreases linearly in steps over time, within a bounded range. | ||
* The rate of change is constant. | ||
* Price formula: price = initialPrice +/- slope * timeBucket | ||
*/ | ||
contract BoundedStepwiseLinearPriceAdapter { | ||
|
||
/** | ||
* @dev Calculates and returns the linear price. | ||
* | ||
* @param _timeElapsed Time elapsed since the start of the auction. | ||
* @param _priceAdapterConfigData Encoded bytes representing the linear function parameters. | ||
* | ||
* @return price The price calculated using the linear function. | ||
*/ | ||
function getPrice( | ||
address /* _setToken */, | ||
address /* _component */, | ||
uint256 /* _componentQuantity */, | ||
uint256 _timeElapsed, | ||
uint256 /* _duration */, | ||
bytes memory _priceAdapterConfigData | ||
) | ||
external | ||
pure | ||
returns (uint256 price) | ||
{ | ||
( | ||
uint256 initialPrice, | ||
uint256 slope, | ||
uint256 bucketSize, | ||
bool isDecreasing, | ||
uint256 maxPrice, | ||
uint256 minPrice | ||
) = getDecodedData(_priceAdapterConfigData); | ||
|
||
require( | ||
areParamsValid(initialPrice, slope, bucketSize, maxPrice, minPrice), | ||
"BoundedStepwiseLinearPriceAdapter: Invalid params" | ||
); | ||
|
||
uint256 bucket = _timeElapsed / bucketSize; | ||
|
||
// Protect against priceChange overflow | ||
if (bucket > type(uint256).max / slope) { | ||
return isDecreasing ? minPrice : maxPrice; | ||
} | ||
|
||
uint256 priceChange = bucket * slope; | ||
|
||
if (isDecreasing) { | ||
// Protect against price underflow | ||
if (priceChange > initialPrice) { | ||
return minPrice; | ||
} | ||
return FixedPointMathLib.max(initialPrice - priceChange, minPrice); | ||
} else { | ||
// Protect against price overflow | ||
if (priceChange > type(uint256).max - initialPrice) { | ||
return maxPrice; | ||
} | ||
return FixedPointMathLib.min(initialPrice + priceChange, maxPrice); | ||
} | ||
} | ||
|
||
/** | ||
* @dev Returns true if the price adapter is valid for the given parameters. | ||
* | ||
* @param _priceAdapterConfigData Encoded data for configuring the price adapter. | ||
* | ||
* @return isValid Boolean indicating if the adapter config data is valid. | ||
*/ | ||
function isPriceAdapterConfigDataValid( | ||
bytes memory _priceAdapterConfigData | ||
) | ||
external | ||
pure | ||
returns (bool isValid) | ||
{ | ||
( | ||
uint256 initialPrice, | ||
uint256 slope, | ||
uint256 bucketSize, | ||
, | ||
uint256 maxPrice, | ||
uint256 minPrice | ||
) = getDecodedData(_priceAdapterConfigData); | ||
|
||
return areParamsValid(initialPrice, slope, bucketSize, maxPrice, minPrice); | ||
} | ||
|
||
/** | ||
* @dev Returns true if the price adapter parameters are valid. | ||
* | ||
* @param _initialPrice Initial price of the auction | ||
* @param _bucketSize Time elapsed between each bucket | ||
* @param _maxPrice Maximum price of the auction | ||
* @param _minPrice Minimum price of the auction | ||
*/ | ||
function areParamsValid( | ||
uint256 _initialPrice, | ||
uint256 _slope, | ||
uint256 _bucketSize, | ||
uint256 _maxPrice, | ||
uint256 _minPrice | ||
) | ||
public | ||
pure | ||
returns (bool) | ||
{ | ||
return _initialPrice > 0 | ||
&& _slope > 0 | ||
&& _bucketSize > 0 | ||
&& _initialPrice <= _maxPrice | ||
&& _initialPrice >= _minPrice; | ||
} | ||
|
||
/** | ||
* @dev Returns the encoded data for the price curve parameters | ||
* | ||
* @param _initialPrice Initial price of the auction | ||
* @param _slope Slope of the linear price change | ||
* @param _bucketSize Time elapsed between each bucket | ||
* @param _isDecreasing Flag for whether the price is decreasing or increasing | ||
* @param _maxPrice Maximum price of the auction | ||
* @param _minPrice Minimum price of the auction | ||
*/ | ||
function getEncodedData( | ||
uint256 _initialPrice, | ||
uint256 _slope, | ||
uint256 _bucketSize, | ||
bool _isDecreasing, | ||
uint256 _maxPrice, | ||
uint256 _minPrice | ||
) | ||
external | ||
pure | ||
returns (bytes memory data) | ||
{ | ||
return abi.encode(_initialPrice, _slope, _bucketSize, _isDecreasing, _maxPrice, _minPrice); | ||
} | ||
|
||
/** | ||
* @dev Decodes the parameters from the provided bytes. | ||
* | ||
* @param _data Bytes encoded auction parameters | ||
* @return initialPrice Initial price of the auction | ||
* @return slope Slope of the linear price change | ||
* @return bucketSize Time elapsed between each bucket | ||
* @return isDecreasing Flag for whether the price is decreasing or increasing | ||
* @return maxPrice Maximum price of the auction | ||
* @return minPrice Minimum price of the auction | ||
*/ | ||
function getDecodedData(bytes memory _data) | ||
public | ||
pure | ||
returns (uint256 initialPrice, uint256 slope, uint256 bucketSize, bool isDecreasing, uint256 maxPrice, uint256 minPrice) | ||
{ | ||
return abi.decode(_data, (uint256, uint256, uint256, bool, uint256, uint256)); | ||
} | ||
} |
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
Oops, something went wrong.