@ -1,78 +0,0 @@
|
||||
pragma solidity ^0.4.23;
|
||||
|
||||
|
||||
/**
|
||||
* @title DayLimit
|
||||
* @dev Base contract that enables methods to be protected by placing a linear limit (specifiable)
|
||||
* on a particular resource per calendar day. Is multiowned to allow the limit to be altered.
|
||||
*/
|
||||
contract DayLimit {
|
||||
|
||||
uint256 public dailyLimit;
|
||||
uint256 public spentToday;
|
||||
uint256 public lastDay;
|
||||
|
||||
/**
|
||||
* @dev Constructor that sets the passed value as a dailyLimit.
|
||||
* @param _limit uint256 to represent the daily limit.
|
||||
*/
|
||||
constructor(uint256 _limit) public {
|
||||
dailyLimit = _limit;
|
||||
lastDay = today();
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev sets the daily limit. Does not alter the amount already spent today.
|
||||
* @param _newLimit uint256 to represent the new limit.
|
||||
*/
|
||||
function _setDailyLimit(uint256 _newLimit) internal {
|
||||
dailyLimit = _newLimit;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Resets the amount already spent today.
|
||||
*/
|
||||
function _resetSpentToday() internal {
|
||||
spentToday = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Checks to see if there is enough resource to spend today. If true, the resource may be expended.
|
||||
* @param _value uint256 representing the amount of resource to spend.
|
||||
* @return A boolean that is True if the resource was spent and false otherwise.
|
||||
*/
|
||||
function underLimit(uint256 _value) internal returns (bool) {
|
||||
// reset the spend limit if we're on a different day to last time.
|
||||
if (today() > lastDay) {
|
||||
spentToday = 0;
|
||||
lastDay = today();
|
||||
}
|
||||
// check to see if there's enough left - if so, subtract and return true.
|
||||
// overflow protection // dailyLimit check
|
||||
if (
|
||||
spentToday + _value >= spentToday &&
|
||||
spentToday + _value <= dailyLimit
|
||||
) {
|
||||
spentToday += _value;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Private function to determine today's index
|
||||
* @return uint256 of today's index.
|
||||
*/
|
||||
function today() private view returns (uint256) {
|
||||
// solium-disable-next-line security/no-block-members
|
||||
return block.timestamp / 1 days;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Simple modifier for daily limit.
|
||||
*/
|
||||
modifier limitedDaily(uint256 _value) {
|
||||
require(underLimit(_value));
|
||||
_;
|
||||
}
|
||||
}
|
||||
@ -1,25 +0,0 @@
|
||||
pragma solidity ^0.4.23;
|
||||
|
||||
import "../../contracts/DayLimit.sol";
|
||||
|
||||
|
||||
contract DayLimitMock is DayLimit {
|
||||
uint256 public totalSpending;
|
||||
|
||||
constructor(uint256 _value) public DayLimit(_value) {
|
||||
totalSpending = 0;
|
||||
}
|
||||
|
||||
function attemptSpend(uint256 _value) external limitedDaily(_value) {
|
||||
totalSpending += _value;
|
||||
}
|
||||
|
||||
function setDailyLimit(uint256 _newLimit) external {
|
||||
_setDailyLimit(_newLimit);
|
||||
}
|
||||
|
||||
function resetSpentToday() external {
|
||||
_resetSpentToday();
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,88 +0,0 @@
|
||||
|
||||
import latestTime from './helpers/latestTime';
|
||||
import { increaseTimeTo, duration } from './helpers/increaseTime';
|
||||
|
||||
import assertRevert from './helpers/assertRevert';
|
||||
|
||||
const DayLimitMock = artifacts.require('DayLimitMock');
|
||||
|
||||
contract('DayLimit', function (accounts) {
|
||||
let dayLimit;
|
||||
let initLimit = 10;
|
||||
|
||||
beforeEach(async function () {
|
||||
this.startTime = latestTime();
|
||||
dayLimit = await DayLimitMock.new(initLimit);
|
||||
});
|
||||
|
||||
it('should construct with the passed daily limit', async function () {
|
||||
let dailyLimit = await dayLimit.dailyLimit();
|
||||
assert.equal(initLimit, dailyLimit);
|
||||
});
|
||||
|
||||
it('should be able to spend if daily limit is not reached', async function () {
|
||||
await dayLimit.attemptSpend(8);
|
||||
let spentToday = await dayLimit.spentToday();
|
||||
assert.equal(spentToday, 8);
|
||||
|
||||
await dayLimit.attemptSpend(2);
|
||||
spentToday = await dayLimit.spentToday();
|
||||
assert.equal(spentToday, 10);
|
||||
});
|
||||
|
||||
it('should prevent spending if daily limit is reached', async function () {
|
||||
await dayLimit.attemptSpend(8);
|
||||
let spentToday = await dayLimit.spentToday();
|
||||
assert.equal(spentToday, 8);
|
||||
await assertRevert(dayLimit.attemptSpend(3));
|
||||
});
|
||||
|
||||
it('should allow spending if daily limit is reached and then set higher', async function () {
|
||||
await dayLimit.attemptSpend(8);
|
||||
let spentToday = await dayLimit.spentToday();
|
||||
assert.equal(spentToday, 8);
|
||||
|
||||
await assertRevert(dayLimit.attemptSpend(3));
|
||||
spentToday = await dayLimit.spentToday();
|
||||
assert.equal(spentToday, 8);
|
||||
|
||||
await dayLimit.setDailyLimit(15);
|
||||
await dayLimit.attemptSpend(3);
|
||||
spentToday = await dayLimit.spentToday();
|
||||
assert.equal(spentToday, 11);
|
||||
});
|
||||
|
||||
it('should allow spending if daily limit is reached and then amount spent is reset', async function () {
|
||||
await dayLimit.attemptSpend(8);
|
||||
let spentToday = await dayLimit.spentToday();
|
||||
assert.equal(spentToday, 8);
|
||||
|
||||
await assertRevert(dayLimit.attemptSpend(3));
|
||||
spentToday = await dayLimit.spentToday();
|
||||
assert.equal(spentToday, 8);
|
||||
|
||||
await dayLimit.resetSpentToday();
|
||||
await dayLimit.attemptSpend(3);
|
||||
spentToday = await dayLimit.spentToday();
|
||||
assert.equal(spentToday, 3);
|
||||
});
|
||||
|
||||
it('should allow spending if daily limit is reached and then the next has come', async function () {
|
||||
let limit = 10;
|
||||
let dayLimit = await DayLimitMock.new(limit);
|
||||
|
||||
await dayLimit.attemptSpend(8);
|
||||
let spentToday = await dayLimit.spentToday();
|
||||
assert.equal(spentToday, 8);
|
||||
|
||||
await assertRevert(dayLimit.attemptSpend(3));
|
||||
spentToday = await dayLimit.spentToday();
|
||||
assert.equal(spentToday, 8);
|
||||
|
||||
await increaseTimeTo(this.startTime + duration.days(1));
|
||||
|
||||
await dayLimit.attemptSpend(3);
|
||||
spentToday = await dayLimit.spentToday();
|
||||
assert.equal(spentToday, 3);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user