pragma solidity ^0.4.25; import "./FixedPrice.sol"; contract DynamicPrice is FixedPrice { uint releaseTime; uint lockTimeS; uint incentivePrice = 0; event FundsReleaseEvent(uint _releaseTime, uint _lockTimeS, uint _actualReleaseTime, uint _lockedFunds, uint _amountReturned); event StartService(bool _successPayment, uint _currentTime, uint _releaseTime); mapping(address => AccountData) accounts; // custom data structure to hold locked funds and time struct AccountData { uint balance; uint releaseTime; bool isFinished; } constructor(uint _price, uint _durationSeconds, address _endUserAddress) FixedPrice(_price, _durationSeconds, _endUserAddress) public { } // pay the max amount and lock funds function payService() public payable { require(msg.sender == endUserAddress); require(price > 0); assert(accounts[msg.sender].balance == 0); require(msg.value >= (price + incentivePrice)); uint currentTime = now; // make sure that the incentive cannot be returned (flexible usage period) accounts[msg.sender].balance = msg.value - incentivePrice; accounts[msg.sender].releaseTime = currentTime + durationSeconds; accounts[msg.sender].isFinished = false; emit StartService(true, currentTime, releaseTime); } // check if user has funds due for pay out because lock time is over function triggerReleaseTime() { require(msg.sender == endUserAddress); require(accounts[msg.sender].isFinished != true); // split funds if there is remaining time if (accounts[msg.sender].releaseTime < now) { uint currentTime = now; uint gweiReturn = (accounts[msg.sender].releaseTime - currentTime) * (price / durationSeconds); msg.sender.send(gweiReturn); accounts[msg.sender].balance -= gweiReturn; accounts[msg.sender].isFinished = true; emit FundsReleaseEvent(releaseTime, lockTimeS, currentTime, price, gweiReturn); } } function checkLockState(){ require(msg.sender == owner); uint currentTime = now; if (accounts[endUserAddress].releaseTime >= currentTime) { accounts[msg.sender].isFinished = true; emit FundsReleaseEvent(releaseTime, lockTimeS, currentTime, price, 0); } else { emit FundsReleaseEvent(releaseTime, lockTimeS, currentTime, price, -1); } } function getLockedFunds() constant returns (uint x) { return accounts[msg.sender].balance; } function getReleaseTime() constant returns (uint x) { return accounts[msg.sender].releaseTime; } function getCurrentTime() constant returns (uint x) { return now; } }