2

I have an oracle with a 'getPrice' function that returns the latest ETH/USD price.

Let's say, I am implementing a stablecoin contract which requires over-collateralization with ETH. How will I automatically dissolve a collateralized position when the margin falls below the minimum specified amount if Ether prices fall?

2 Answers 2

1

I think you might be thinking about a general pattern Nick Johnson first wrote about, Amortized Work, https://medium.com/@weka/dividend-bearing-tokens-on-ethereum-42d01c710657

The general idea is to use queues (or conditions) to execute small units of work whenever gas is available. You can use that for garbage collection and other housekeeping/maintenance work. Generally, you attach modifiers to state-changing functions and get someone to pay for a unit, O(1), of background processing.

For example, if you had a prioritized queue of over-collateralized positions and you wanted to clear them out, then you would create a modifier to process one candidate and attach that modifier to each state-changing function. It would clear one candidate every time something (anything) happens.

You can consider all sorts of possible "triggers." For example, it occurs to me that the main stakeholder would be the depositor who is entitled to withdraw from his over-collateralized position. That would be a view function, and it could be written to compute what the world is going to look like even though the state variables have not been adjusted. If they decide to withdraw funds, then there's your "gas payer" who will attend persistent state updates, for their account, which seems fair.

Consider:

contract Amortized {

  mapping(address => uint) balances;

  modifier amortizeWork {
     uint c = balanceOf(msg.sender);
     if(balances[msg.sender] != c {
        ??? // clear out state-altering transactions/work/jobs
        balances[msg.sender] = c; // update the state
     }
  }

  function balanceOf(address a) public view returns(uint computedBalance) {
    computedBalance = balances[a] + ... // compute something
  }

  function doSomething() public amortizeWork ...

The balanceOf function returns the stored balance adjusted for unprocessed work so the UI gets the right number. When it sees a chance, it updates the state. Be mindful of unbounded for loops. It might be smarter to process just one (job, payment, dividend, order, whatever is in the backlog) at a time so it always works and devise a strategy to ensure you are clearing the queue faster than it is growing.

Hope it helps.

2
  • Are you suggesting that every time a state-changing function is called, they should also call a modifier that makes a call to update the ETH/USD price? It seems like they would have to make a call to their getPrice function at some regular interval. Or some node off-chain could call to update the price. Commented Jun 15, 2020 at 21:32
  • 1
    I was addressing "How will I automatically dissolve a collateralized position" but it's a general answer to a general question without much knowledge of the detailed requirements. I added a little example of a generalized pattern. Commented Jun 16, 2020 at 19:20
0

There are several ways to achieve something similar.

For example MakerDao has an oracle contract that contains the prices submitted by a group of whitelisted addresses.

When the price is required for MakerDao regular operation it will take the median price in the oracle contract.

Prices are submitted regularly or when it changes above certain threshold.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.