From af8401d3e9ce8674eddcc29a3d13fca3c5bb0d49 Mon Sep 17 00:00:00 2001 From: rotcivegaf Date: Tue, 28 May 2019 16:29:40 -0300 Subject: [PATCH 1/9] add documentation --- .../core/diaspore/model/InstallmentsModel.sol | 68 ++++++++++++++++--- 1 file changed, 60 insertions(+), 8 deletions(-) diff --git a/contracts/core/diaspore/model/InstallmentsModel.sol b/contracts/core/diaspore/model/InstallmentsModel.sol index 0c0e51b1..650b7d02 100644 --- a/contracts/core/diaspore/model/InstallmentsModel.sol +++ b/contracts/core/diaspore/model/InstallmentsModel.sol @@ -16,12 +16,18 @@ contract InstallmentsModel is ERC165, BytesUtils, Ownable, Model, ModelDescripto _registerInterface(MODEL_DESCRIPTOR_INTERFACE); } - address public engine; + address public engine; // The DebtEngine contract address private altDescriptor; mapping(bytes32 => Config) public configs; mapping(bytes32 => State) public states; + // L_DATA = + // 16 bytes to uint128 cuota + + // 32 bytes to uint256 interestRate + + // 3 bytes to uint24 installments + + // 5 bytes to uint40 duration + + // 4 bytes to uint32 timeUnit uint256 public constant L_DATA = 16 + 32 + 3 + 5 + 4; uint256 private constant U_128_OVERFLOW = 2 ** 128; @@ -36,17 +42,25 @@ contract InstallmentsModel is ERC165, BytesUtils, Ownable, Model, ModelDescripto event _setPaidBase(bytes32 _id, uint128 _paidBase); event _setInterest(bytes32 _id, uint128 _interest); + /** + The Config struct be use to storage the constants of a debt, + this constants not be overwrite + */ struct Config { - uint24 installments; - uint32 timeUnit; - uint40 duration; - uint64 lentTime; - uint128 cuota; - uint256 interestRate; + uint24 installments; // The installments of the debt + uint32 timeUnit; // The minimum unit for which interest is added + uint40 duration; // The duration of each installment + uint64 lentTime; // The timestamp in which a debt was created + uint128 cuota; // The amount in WEI of each installment + uint256 interestRate; // The interest rate is defined as a denominator of 10 000 000 } + /** + The State struct be use to storage the variables of a debt + */ struct State { - uint8 status; + uint8 status; // Status of the debt, can is 0 if the debt is ongoing or not exist and + // can be STATUS_PAID if the debt is fully paid uint64 clock; uint64 lastPayment; uint128 paid; @@ -54,6 +68,9 @@ contract InstallmentsModel is ERC165, BytesUtils, Ownable, Model, ModelDescripto uint128 interest; } + /** + Use in create(), addPaid(), addDebt() functions + */ modifier onlyEngine { require(msg.sender == engine, "Only engine allowed"); _; @@ -69,6 +86,11 @@ contract InstallmentsModel is ERC165, BytesUtils, Ownable, Model, ModelDescripto return _descriptor == address(0) ? address(this) : _descriptor; } + /** + Setter of engine, used in onlyEngine modifier + + @param _engine DebtEngine address + */ function setEngine(address _engine) external onlyOwner returns (bool) { engine = _engine; emit _setEngine(_engine); @@ -195,6 +217,11 @@ contract InstallmentsModel is ERC165, BytesUtils, Ownable, Model, ModelDescripto return _advanceClock(id, targetClock); } + /** + @param _target Target address + + @return if the target is the operator of the model + */ function isOperator(address _target) external view returns (bool) { return engine == _target; } @@ -280,6 +307,15 @@ contract InstallmentsModel is ERC165, BytesUtils, Ownable, Model, ModelDescripto return _advanceClock(id, uint64(now) - config.lentTime); } + /** + @dev Look in _validate function documentation for more information + + @param data Array of bytes parameters, used to create a debt + * look in _decodeData function documentation for more information + + @return True if can validate the data + revert if cant validate the data + */ function validate(bytes calldata data) external view returns (bool) { (uint128 cuota, uint256 interestRate, uint24 installments, uint40 duration, uint32 timeUnit) = _decodeData(data); _validate(cuota, interestRate, installments, duration, timeUnit); @@ -499,6 +535,7 @@ contract InstallmentsModel is ERC165, BytesUtils, Ownable, Model, ModelDescripto uint256 cuota ) internal pure returns (uint256 base) { uint256 installment = clock / duration; + // min(installment, installments) * cuota return uint128(installment < installments ? installment * cuota : installments * cuota); } @@ -518,6 +555,21 @@ contract InstallmentsModel is ERC165, BytesUtils, Ownable, Model, ModelDescripto require(_timeUnit > 0, "Time unit can'be 0"); } + /** + @notice Decode bytes array and returns the parameters of a debt + + @dev The length of data should be L_DATA (the sum of the length of the debt parameters in bytes) + + @param _data Index of the debt + from-to bytes + 0 -16: cuota + 16-48: interestRate + 48-51: installments + 51-56: duration + 56-60: timeUnit + + @return Look in config struct documentation for more information + */ function _decodeData( bytes memory _data ) internal pure returns (uint128, uint256, uint24, uint40, uint32) { From f70d8210cbf9565884a87523670f4ccb8a5573cb Mon Sep 17 00:00:00 2001 From: rotcivegaf Date: Tue, 28 May 2019 18:38:12 -0300 Subject: [PATCH 2/9] add documentation --- .../core/diaspore/model/InstallmentsModel.sol | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/contracts/core/diaspore/model/InstallmentsModel.sol b/contracts/core/diaspore/model/InstallmentsModel.sol index 650b7d02..186f760d 100644 --- a/contracts/core/diaspore/model/InstallmentsModel.sol +++ b/contracts/core/diaspore/model/InstallmentsModel.sol @@ -113,6 +113,13 @@ contract InstallmentsModel is ERC165, BytesUtils, Ownable, Model, ModelDescripto return abi.encodePacked(_cuota, _interestRate, _installments, _duration, _timeUnit); } + /** + @dev Before create the debt the data should be validate with call _validate function + + @param id Index of the debt + @param data Array of bytes parameters, used to create a debt + * look in _decodeData function documentation for more info + */ function create(bytes32 id, bytes calldata data) external onlyEngine returns (bool) { require(configs[id].cuota == 0, "Entry already exist"); @@ -136,6 +143,20 @@ contract InstallmentsModel is ERC165, BytesUtils, Ownable, Model, ModelDescripto return true; } + /** + @notice Pay loan + + Does a payment of a given debt, before performing the payment the accumulated + interest is computed and added to the total pending amount. + + If the paid pending amount equals zero, the debt changes status to "paid" and + it is considered closed. + + @param id Index of the debt + @param amount Amount to pay + + @return toPay if the payment was executed successfully + */ function addPaid(bytes32 id, uint256 amount) external onlyEngine returns (uint256 real) { Config storage config = configs[id]; State storage state = states[id]; @@ -302,6 +323,13 @@ contract InstallmentsModel is ERC165, BytesUtils, Ownable, Model, ModelDescripto }); } + /** + @notice Updates the debt accumulated interests up to the current Unix time. + + @param id Index of the debt + + @return true If the interest was updated + */ function run(bytes32 id) external returns (bool) { Config storage config = configs[id]; return _advanceClock(id, uint64(now) - config.lentTime); @@ -379,6 +407,14 @@ contract InstallmentsModel is ERC165, BytesUtils, Ownable, Model, ModelDescripto (,, installments,,) = _decodeData(_data); } + /** + @notice Updates the debt accumulated interests up to the _target + + @param id Index of the debt + @param _target Timestamp target to advance the clock + + @return true If the interest was updated + */ function _advanceClock(bytes32 id, uint256 _target) internal returns (bool) { Config storage config = configs[id]; State storage state = states[id]; @@ -539,6 +575,15 @@ contract InstallmentsModel is ERC165, BytesUtils, Ownable, Model, ModelDescripto return uint128(installment < installments ? installment * cuota : installments * cuota); } + /** + Use to validate a debt + To more information of params look in config struct documentation + + @dev Validate the debt parameters + The _cuota, _installments, _timeUnit should not be 0 + The _interestRate should be grater or equal than _timeUnit + The _installmentDuration should be grater than _timeUnit + */ function _validate( uint256 _cuota, uint256 _interestRate, From c265bd554fa2f9bbd6d7c8e8066d1ab3154b51ad Mon Sep 17 00:00:00 2001 From: rotcivegaf Date: Wed, 29 May 2019 13:59:23 -0300 Subject: [PATCH 3/9] fix addPaid return doc --- contracts/core/diaspore/model/InstallmentsModel.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/core/diaspore/model/InstallmentsModel.sol b/contracts/core/diaspore/model/InstallmentsModel.sol index 186f760d..e9510ba3 100644 --- a/contracts/core/diaspore/model/InstallmentsModel.sol +++ b/contracts/core/diaspore/model/InstallmentsModel.sol @@ -155,7 +155,7 @@ contract InstallmentsModel is ERC165, BytesUtils, Ownable, Model, ModelDescripto @param id Index of the debt @param amount Amount to pay - @return toPay if the payment was executed successfully + @return Total paid amount */ function addPaid(bytes32 id, uint256 amount) external onlyEngine returns (uint256 real) { Config storage config = configs[id]; From 7c2bb4db632180af8fd7fe39e9caf3adb8bea2d0 Mon Sep 17 00:00:00 2001 From: rotcivegaf Date: Wed, 29 May 2019 14:38:50 -0300 Subject: [PATCH 4/9] add state comments --- contracts/core/diaspore/model/InstallmentsModel.sol | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/contracts/core/diaspore/model/InstallmentsModel.sol b/contracts/core/diaspore/model/InstallmentsModel.sol index e9510ba3..c004e5b6 100644 --- a/contracts/core/diaspore/model/InstallmentsModel.sol +++ b/contracts/core/diaspore/model/InstallmentsModel.sol @@ -61,11 +61,12 @@ contract InstallmentsModel is ERC165, BytesUtils, Ownable, Model, ModelDescripto struct State { uint8 status; // Status of the debt, can is 0 if the debt is ongoing or not exist and // can be STATUS_PAID if the debt is fully paid - uint64 clock; - uint64 lastPayment; - uint128 paid; - uint128 paidBase; - uint128 interest; + uint64 clock; // Storage the timestamp of last interest calculate + uint64 lastPayment; // The timestamp of the last payment, which the clock was able + // to advance, look in addPaid function + uint128 paid; // Accumulator of payment, cuota + interest + uint128 paidBase; // Accumulator of cuota payments, without interest + uint128 interest; // Accumulator of interest amount } /** From 270a4e341a1ebcd530fdd99f88ef854b17bc76a9 Mon Sep 17 00:00:00 2001 From: rotcivegaf Date: Fri, 31 May 2019 19:46:48 -0300 Subject: [PATCH 5/9] add comments and doc --- contracts/core/diaspore/DebtEngine.sol | 85 ++++++++++++++++++++++---- 1 file changed, 74 insertions(+), 11 deletions(-) diff --git a/contracts/core/diaspore/DebtEngine.sol b/contracts/core/diaspore/DebtEngine.sol index 0e53c9b2..03aa5bb5 100644 --- a/contracts/core/diaspore/DebtEngine.sol +++ b/contracts/core/diaspore/DebtEngine.sol @@ -83,19 +83,26 @@ contract DebtEngine is ERC721Base, Ownable { bytes _callData ); + // This Token(ERC20) works like the fuel of our engine, + // when lend or pay a debt use this Token IERC20 public token; - + // The array to storage the debs mapping(bytes32 => Debt) public debts; + // Used in create function, increment every create mapping(address => uint256) public nonces; struct Debt { - bool error; - uint128 balance; - Model model; + bool error; // Used to mark a debt in ERROR status + uint128 balance; // Balance of the debt + Model model; // Model of the debt address creator; - address oracle; + address oracle; // Oracle of the debt, if is address(0) the debt is in Token + // in other case the debt use the oracle to get the rate } + /** + @notice Set the Token + */ constructor ( IERC20 _token ) public ERC721Base("RCN Debt Record", "RDR") { @@ -105,17 +112,38 @@ contract DebtEngine is ERC721Base, Ownable { require(address(_token).isContract(), "Token should be a contract"); } + /** + @notice Set provider, look in ERC721Base + + @dev Only the owner can use this function + */ function setURIProvider(URIProvider _provider) external onlyOwner { _setURIProvider(_provider); } + /** + @notice Create a debt + + @dev Hash (uint8(1), address(this), msg.sender, nonce) to make the id + + @param _model Model of the debt + @param _owner Owner of the ERC721 and the debt + @param _oracle Oracle of the debt, if is address(0) the debt is in Token + in other case the debt use the oracle to get the rate + @param _data Array of bytes parameters, send to the Model contract with + the create function + + @return The id if the debt + */ function create( Model _model, address _owner, address _oracle, bytes calldata _data ) external returns (bytes32 id) { + // Increment the nonce of the sender uint256 nonce = nonces[msg.sender]++; + // Calculate the id of the debt id = keccak256( abi.encodePacked( uint8(1), @@ -124,7 +152,7 @@ contract DebtEngine is ERC721Base, Ownable { nonce ) ); - + // Add the debt to the debts array debts[id] = Debt({ error: false, balance: 0, @@ -132,8 +160,9 @@ contract DebtEngine is ERC721Base, Ownable { model: _model, oracle: _oracle }); - + // Generate the ERC721 _generate(uint256(id), _owner); + // Execute the create function of the model require(_model.create(id, _data), "Error creating debt in model"); emit Created({ @@ -143,6 +172,21 @@ contract DebtEngine is ERC721Base, Ownable { }); } + /** + @notice Create a debt + + @dev Hash (uint8(2), address(this), msg.sender, _model, _oracle, _salt, _data) to make the id + + @param _model Model of the debt + @param _owner Owner of the ERC721 and the debt + @param _oracle Oracle of the debt, if is address(0) the debt is in Token + in other case the debt use the oracle to get the rate + @param _salt Add entropy to the hash id + @param _data Array of bytes parameters, send to the Model contract with + the create function + + @return The id if the debt + */ function create2( Model _model, address _owner, @@ -150,6 +194,7 @@ contract DebtEngine is ERC721Base, Ownable { uint256 _salt, bytes calldata _data ) external returns (bytes32 id) { + // Calculate the id of the debt id = keccak256( abi.encodePacked( uint8(2), @@ -161,7 +206,7 @@ contract DebtEngine is ERC721Base, Ownable { _data ) ); - + // Add the debt to the debts array debts[id] = Debt({ error: false, balance: 0, @@ -169,8 +214,9 @@ contract DebtEngine is ERC721Base, Ownable { model: _model, oracle: _oracle }); - + // Generate the ERC721 _generate(uint256(id), _owner); + // Execute the create function of the model require(_model.create(id, _data), "Error creating debt in model"); emit Created2({ @@ -180,6 +226,21 @@ contract DebtEngine is ERC721Base, Ownable { }); } + /** + @notice Create a debt + + @dev Hash (uint8(3), address(this), msg.sender, _salt) to make the id + + @param _model Model of the debt + @param _owner Owner of the ERC721 and the debt + @param _oracle Oracle of the debt, if is address(0) the debt is in Token + in other case the debt use the oracle to get the rate + @param _salt Add entropy to the hash id + @param _data Array of bytes parameters, send to the Model contract with + the create function + + @return The id if the debt + */ function create3( Model _model, address _owner, @@ -187,6 +248,7 @@ contract DebtEngine is ERC721Base, Ownable { uint256 _salt, bytes calldata _data ) external returns (bytes32 id) { + // Calculate the id of the debt id = keccak256( abi.encodePacked( uint8(3), @@ -195,7 +257,7 @@ contract DebtEngine is ERC721Base, Ownable { _salt ) ); - + // Add the debt to the debts array debts[id] = Debt({ error: false, balance: 0, @@ -203,8 +265,9 @@ contract DebtEngine is ERC721Base, Ownable { model: _model, oracle: _oracle }); - + // Generate the ERC721 _generate(uint256(id), _owner); + // Execute the create function of the model require(_model.create(id, _data), "Error creating debt in model"); emit Created3({ From 312d82448ab51317818864df99246827ef5f9cd6 Mon Sep 17 00:00:00 2001 From: rotcivegaf Date: Fri, 31 May 2019 19:52:02 -0300 Subject: [PATCH 6/9] Add builds documentation --- contracts/core/diaspore/DebtEngine.sol | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/contracts/core/diaspore/DebtEngine.sol b/contracts/core/diaspore/DebtEngine.sol index 03aa5bb5..8f9dbe2f 100644 --- a/contracts/core/diaspore/DebtEngine.sol +++ b/contracts/core/diaspore/DebtEngine.sol @@ -277,6 +277,9 @@ contract DebtEngine is ERC721Base, Ownable { }); } + /** + @notice Getter of id when use create function + */ function buildId( address _creator, uint256 _nonce @@ -291,6 +294,9 @@ contract DebtEngine is ERC721Base, Ownable { ); } + /** + @notice Getter of id when use create2 function + */ function buildId2( address _creator, address _model, @@ -311,6 +317,9 @@ contract DebtEngine is ERC721Base, Ownable { ); } + /** + @notice Getter of id when use create3 function + */ function buildId3( address _creator, uint256 _salt From e5a288667d24f014e1a75d4a413968bac6e54fc1 Mon Sep 17 00:00:00 2001 From: rotcivegaf Date: Mon, 3 Jun 2019 16:32:21 -0300 Subject: [PATCH 7/9] add doc --- contracts/core/diaspore/DebtEngine.sol | 55 ++++++++++++++++++++------ 1 file changed, 43 insertions(+), 12 deletions(-) diff --git a/contracts/core/diaspore/DebtEngine.sol b/contracts/core/diaspore/DebtEngine.sol index 8f9dbe2f..b275c56e 100644 --- a/contracts/core/diaspore/DebtEngine.sol +++ b/contracts/core/diaspore/DebtEngine.sol @@ -95,7 +95,7 @@ contract DebtEngine is ERC721Base, Ownable { bool error; // Used to mark a debt in ERROR status uint128 balance; // Balance of the debt Model model; // Model of the debt - address creator; + address creator; // The sender of the create, create2, create3 functions address oracle; // Oracle of the debt, if is address(0) the debt is in Token // in other case the debt use the oracle to get the rate } @@ -334,6 +334,18 @@ contract DebtEngine is ERC721Base, Ownable { ); } + /** + @notice Pay a debt + + @dev The contract takes the funds from the sender but the really payer is the _origin + + @param _id Index of the debt + @param _amount The maximum amount of the payment, valued in the currency of the debt + @param _origin The originator of the payment + @param _oracleData Data of oracle to change the currency of debt to the Token + + @return How much was really paid valued in the currency of the debt and in the token + */ function pay( bytes32 _id, uint256 _amount, @@ -344,18 +356,20 @@ contract DebtEngine is ERC721Base, Ownable { // Paid only required amount paid = _safePay(_id, debt.model, _amount); require(paid <= _amount, "Paid can't be more than requested"); - + // Get the oracle RateOracle oracle = RateOracle(debt.oracle); - if (address(oracle) != address(0)) { - // Convert + + if (address(oracle) != address(0)) { // Debt in currency + // Read oracle (uint256 tokens, uint256 equivalent) = oracle.readSample(_oracleData); emit ReadedOracle(_id, tokens, equivalent); + // Convert the paid amount from currency of debt to Token paidToken = _toToken(paid, tokens, equivalent); - } else { + } else { // Debt in the Token paidToken = paid; } - // Pull tokens from payer + // Pull tokens from payer(sender) require(token.transferFrom(msg.sender, address(this), paidToken), "Error pulling payment tokens"); // Add balance to the debt @@ -375,6 +389,18 @@ contract DebtEngine is ERC721Base, Ownable { }); } + /** + @notice Pay a debt with token + + @dev The contract takes the funds from the sender but the really payer is the _origin + + @param _id Index of the debt + @param _amount The amount of the payment, valued in the Token + @param _origin The originator of the payment + @param _oracleData Data of oracle to change the currency of debt to the Token + + @return How much was really paid valued in the currency of the debt and in the token + */ function payToken( bytes32 id, uint256 amount, @@ -382,7 +408,7 @@ contract DebtEngine is ERC721Base, Ownable { bytes calldata oracleData ) external returns (uint256 paid, uint256 paidToken) { Debt storage debt = debts[id]; - // Read storage + // Get the oracle RateOracle oracle = RateOracle(debt.oracle); uint256 equivalent; @@ -390,11 +416,13 @@ contract DebtEngine is ERC721Base, Ownable { uint256 available; // Get available amount - if (address(oracle) != address(0)) { + if (address(oracle) != address(0)) { // Debt in currency + // Read oracle (tokens, equivalent) = oracle.readSample(oracleData); emit ReadedOracle(id, tokens, equivalent); + // Convert the paid amount from Token to currency of debt available = _fromToken(amount, tokens, equivalent); - } else { + } else { // Debt in the Token available = amount; } @@ -403,10 +431,11 @@ contract DebtEngine is ERC721Base, Ownable { require(paid <= available, "Paid can't exceed available"); // Convert back to required pull amount - if (address(oracle) != address(0)) { + if (address(oracle) != address(0)) { // Debt in currency + // Convert the paid amount from currency of debt to Token paidToken = _toToken(paid, tokens, equivalent); require(paidToken <= amount, "Paid can't exceed requested"); - } else { + } else { // Debt in the Token paidToken = paid; } @@ -444,6 +473,7 @@ contract DebtEngine is ERC721Base, Ownable { uint256 tokens; uint256 equivalent; if (_oracle != address(0)) { + // Read oracle (tokens, equivalent) = RateOracle(_oracle).readSample(_oracleData); emit ReadedOracleBatch(_oracle, count, tokens, equivalent); } @@ -478,7 +508,8 @@ contract DebtEngine is ERC721Base, Ownable { uint256 tokens; uint256 equivalent; - if (_oracle != address(0)) { + if (_oracle != address(0)) {// Read oracle + // Read oracle (tokens, equivalent) = RateOracle(_oracle).readSample(_oracleData); emit ReadedOracleBatch(_oracle, count, tokens, equivalent); } From 87c1969dfa4af58a8fdf99e74f51e51ebc6fbfed Mon Sep 17 00:00:00 2001 From: rotcivegaf Date: Mon, 10 Jun 2019 18:54:45 -0300 Subject: [PATCH 8/9] fix doc remove _ --- contracts/core/diaspore/DebtEngine.sol | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/contracts/core/diaspore/DebtEngine.sol b/contracts/core/diaspore/DebtEngine.sol index b275c56e..4b92a2ec 100644 --- a/contracts/core/diaspore/DebtEngine.sol +++ b/contracts/core/diaspore/DebtEngine.sol @@ -394,10 +394,10 @@ contract DebtEngine is ERC721Base, Ownable { @dev The contract takes the funds from the sender but the really payer is the _origin - @param _id Index of the debt - @param _amount The amount of the payment, valued in the Token - @param _origin The originator of the payment - @param _oracleData Data of oracle to change the currency of debt to the Token + @param id Index of the debt + @param amount The amount of the payment, valued in the Token + @param origin The originator of the payment + @param oracleData Data of oracle to change the currency of debt to the Token @return How much was really paid valued in the currency of the debt and in the token */ From bc43a2093f2745478fe7558d139a8937b6cfd460 Mon Sep 17 00:00:00 2001 From: rotcivegaf Date: Wed, 12 Jun 2019 19:20:25 -0300 Subject: [PATCH 9/9] update installments molde documentation --- .../core/diaspore/model/InstallmentsModel.sol | 83 +++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/contracts/core/diaspore/model/InstallmentsModel.sol b/contracts/core/diaspore/model/InstallmentsModel.sol index 52df7d2f..0f12e9bc 100644 --- a/contracts/core/diaspore/model/InstallmentsModel.sol +++ b/contracts/core/diaspore/model/InstallmentsModel.sol @@ -77,11 +77,17 @@ contract InstallmentsModel is ERC165, BytesUtils, Ownable, Model, ModelDescripto _; } + /** + Getter of version of model in bytes32 + */ function modelId() external view returns (bytes32) { // InstallmentsModel A 0.0.2 return bytes32(0x00000000000000496e7374616c6c6d656e74734d6f64656c204120302e302e32); } + /** + Getter the address of the descriptor + */ function descriptor() external view returns (address) { address _descriptor = altDescriptor; return _descriptor == address(0) ? address(this) : _descriptor; @@ -90,6 +96,8 @@ contract InstallmentsModel is ERC165, BytesUtils, Ownable, Model, ModelDescripto /** Setter of engine, used in onlyEngine modifier + @dev Only the owner of the contract can use this function + @param _engine DebtEngine address */ function setEngine(address _engine) external onlyOwner returns (bool) { @@ -98,6 +106,13 @@ contract InstallmentsModel is ERC165, BytesUtils, Ownable, Model, ModelDescripto return true; } + /** + Setter of altDescriptor, used to describe the model, should implements the ModelDescriptor interface + + @dev Only the owner of the contract can use this function + + @param _descriptor Descriptor address + */ function setDescriptor(address _descriptor) external onlyOwner returns (bool) { altDescriptor = _descriptor; emit _setDescriptor(_descriptor); @@ -116,6 +131,7 @@ contract InstallmentsModel is ERC165, BytesUtils, Ownable, Model, ModelDescripto /** @dev Before create the debt the data should be validate with call _validate function + Only the engine can use this function @param id Index of the debt @param data Array of bytes parameters, used to create a debt @@ -153,6 +169,8 @@ contract InstallmentsModel is ERC165, BytesUtils, Ownable, Model, ModelDescripto If the paid pending amount equals zero, the debt changes status to "paid" and it is considered closed. + @dev Only the engine can use this function + @param id Index of the debt @param amount Amount to pay @@ -224,10 +242,25 @@ contract InstallmentsModel is ERC165, BytesUtils, Ownable, Model, ModelDescripto } } + /** + Always revert, its not implemented + + @dev Only the engine can use this function + */ function addDebt(bytes32 id, uint256 amount) external onlyEngine returns (bool) { revert("Not implemented!"); } + /** + @notice Advance a clock to a target clock + + @dev Used when the clock cant advance in a addPaid or run, because this methods consumed all gas + + @param id Index of the debt + @param target Timestamp target to advance the clock + + @return If the fix clock can execute + */ function fixClock(bytes32 id, uint64 target) external returns (bool) { require(target <= now, "Forbidden advance clock into the future"); Config storage config = configs[id]; @@ -304,6 +337,15 @@ contract InstallmentsModel is ERC165, BytesUtils, Ownable, Model, ModelDescripto return (debt > paid ? debt - paid : 0, defined); } + /** + @param _clock The state.clock(always the same) + @param _targetClock Timestamp target + @param _prevInterest The state.interest(always the same) + @param _config A config of a loan + @param _state A State of a loan + + @return TODO + */ function _simRunClock( uint256 _clock, uint256 _targetClock, @@ -483,6 +525,19 @@ contract InstallmentsModel is ERC165, BytesUtils, Ownable, Model, ModelDescripto return debt > paid ? debt - paid : 0; } + /** + @param _clock The state.clock(always the same) + @param _timeUnit The config.timeUnit(always the same) + @param _interest The state.interest(always the same) + @param _duration The config.duration(always the same) + @param _cuota The config.cuota(always the same) + @param _installments The config.installments(always the same) + @param _paidBase The state.paidBase(always the same) + @param _interestRate The config.interestRate(always the same) + @param _targetClock Timestamp target to advance the clock + + @return TODO + */ function _runAdvanceClock( uint256 _clock, uint256 _timeUnit, @@ -533,6 +588,14 @@ contract InstallmentsModel is ERC165, BytesUtils, Ownable, Model, ModelDescripto } while (clock < _targetClock); } + /** + @param _targetDelta TODO + @param _clock The state.clock(always the same) + @param _duration The config.duration(always the same) + @param _installments The config.installments(always the same) + + @return TODO + */ function _calcDelta( uint256 _targetDelta, uint256 _clock, @@ -549,6 +612,18 @@ contract InstallmentsModel is ERC165, BytesUtils, Ownable, Model, ModelDescripto } } + /** + @param _clock The state.clock(always the same) + @param _timeUnit The config.timeUnit(always the same) + @param _duration The config.duration(always the same) + @param _installments The config.installments(always the same) + @param _cuota The config.cuota(always the same) + @param _paidBase The state.paidBase(always the same) + @param _delta TODO + @param _interestRate The config.interestRate(always the same) + + @return TODO + */ function _newInterest( uint256 _clock, uint256 _timeUnit, @@ -565,6 +640,14 @@ contract InstallmentsModel is ERC165, BytesUtils, Ownable, Model, ModelDescripto return newInterest; } + /** + @param clock TODO + @param duration The config.duration(always the same) + @param installments The config.installmens(always the same) + @param cuota The config.cuota(always the same) + + @return The baseDebt of the sent clock + */ function _baseDebt( uint256 clock, uint256 duration,