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.