Skip to content

Commit

Permalink
Merge pull request #7 from aboutcircles/20240607-inflationary-interface
Browse files Browse the repository at this point in the history
(circle): re-introduce inflationary balance of and safeTransfer
  • Loading branch information
benjaminbollen committed Jun 10, 2024
2 parents af7ff96 + 3560a96 commit 6a9b9c3
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 2 deletions.
59 changes: 59 additions & 0 deletions src/circles/Circles.sol
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,65 @@ contract Circles is ERC1155, ICirclesErrors {
);
}

/**
* Inflationary balance of an account for a Circles identifier. Careful,
* calculating the inflationary balance can introduce numerical errors
* in the least significant digits (order of few attoCircles).
* @param _account Address for which the balance is queried.
* @param _id Circles identifier for which the balance is queried.
*/
function inflationaryBalanceOf(address _account, uint256 _id) public view returns (uint256) {
return _inflationaryBalanceOf(_account, _id);
}

/**
* @notice safeInflationaryTransferFrom transfers Circles from one address to another by specifying inflationary units.
* @param _from Address from which the Circles are transferred.
* @param _to Address to which the Circles are transferred.
* @param _id Circles indentifier for which the Circles are transferred.
* @param _inflationaryValue Inflationary value of the Circles transferred.
* @param _data Data to pass to the receiver.
*/
function safeInflationaryTransferFrom(
address _from,
address _to,
uint256 _id,
uint256 _inflationaryValue,
bytes memory _data
) public {
address sender = _msgSender();
if (_from != sender && !isApprovedForAll(_from, sender)) {
revert ERC1155MissingApprovalForAll(sender, _from);
}
// convert inflationary value to todays demurrage value
uint256 value = convertInflationaryToDemurrageValue(_inflationaryValue, day(block.timestamp));
_safeTransferFrom(_from, _to, _id, value, _data);
}

/**
* @notice safeInflationaryBatchTransferFrom transfers Circles from one address to another by specifying inflationary units.
* @param _from Address from which the Circles are transferred.
* @param _to Address to which the Circles are transferred.
* @param _ids Batch of Circles identifiers for which the Circles are transferred.
* @param _inflationaryValues Batch of inflationary values of the Circles transferred.
* @param _data Data to pass to the receiver.
*/
function safeInflationaryBatchTransferFrom(
address _from,
address _to,
uint256[] memory _ids,
uint256[] memory _inflationaryValues,
bytes memory _data
) public {
address sender = _msgSender();
if (_from != sender && !isApprovedForAll(_from, sender)) {
revert ERC1155MissingApprovalForAll(sender, _from);
}
uint64 today = day(block.timestamp);
uint256[] memory values = convertBatchInflationaryToDemurrageValues(_inflationaryValues, today);
_safeBatchTransferFrom(_from, _to, _ids, values, _data);
}

// Internal functions

/**
Expand Down
5 changes: 3 additions & 2 deletions src/circles/Demurrage.sol
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,8 @@ contract Demurrage is ICirclesDemurrageErrors {
// calculate the demurrage value by multiplying the value by GAMMA^days
// note: GAMMA < 1, so multiplying by a power of it, returns a smaller number,
// so we lose the least significant bits, but our ground truth is the demurrage value,
// and the inflationary value the numerical approximation.
// and the inflationary value is a numerical approximation (where the least significant digits
// are not reliable).
int128 r = Math64x64.pow(GAMMA_64x64, uint256(_day));
return Math64x64.mulu(r, _inflationaryValue);
}
Expand Down Expand Up @@ -270,7 +271,7 @@ contract Demurrage is ICirclesDemurrageErrors {
function _calculateInflationaryBalance(uint256 _balance, uint256 _dayUpdated) internal pure returns (uint256) {
// calculate the inflationary balance by dividing the balance by GAMMA^days
// note: GAMMA < 1, so dividing by a power of it, returns a bigger number,
// so the numerical inprecision is in the least significant bits.
// so the numerical imprecision is in the least significant bits.
int128 i = Math64x64.pow(BETA_64x64, _dayUpdated);
return Math64x64.mulu(i, _balance);
}
Expand Down
10 changes: 10 additions & 0 deletions src/circles/DiscountedBalances.sol
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,16 @@ contract DiscountedBalances is Demurrage {

// Internal functions

/**
* @dev Calculate the inflationary balance of a discounted balance
* @param _account Address of the account to calculate the balance of
* @param _id Circles identifier for which to calculate the balance
*/
function _inflationaryBalanceOf(address _account, uint256 _id) internal view returns (uint256) {
DiscountedBalance memory discountedBalance = discountedBalances[_id][_account];
return _calculateInflationaryBalance(discountedBalance.balance, discountedBalance.lastUpdatedDay);
}

/**
* @dev Update the balance of an account for a given Circles identifier
* @param _account Address of the account to update the balance of
Expand Down

0 comments on commit 6a9b9c3

Please sign in to comment.