} from "@superfluid-finance/ethereum-contracts/contracts/interfaces/superfluid/ISuperfluid.sol";
IInstantDistributionAgreementV1
} from "@superfluid-finance/ethereum-contracts/contracts/interfaces/agreements/IInstantDistributionAgreementV1.sol";
} from "@superfluid-finance/ethereum-contracts/contracts/apps/IDAv1Library.sol";
/// @title Simple Recurring Airdrop contract example.
/// @notice This is NOT suitable for production, this is for demonstration ONLY.
contract RecurringAirdropper {
using IDAv1Library for IDAv1Library.InitData;
IDAv1Library.InitData internal _idav1Lib;
uint32 internal constant _INDEX_ID = 0;
address internal immutable _ADMIN;
ISuperfluidToken public token;
uint256 public lastAirdrop;
uint256 public constant AIRDROP_INTERVAL = 30 days;
uint256 public constant AIRDROP_AMOUNT = 1e23; // 100_000 * 1e18
IInstantDistributionAgreement _ida,
_idav1Lib = IDAv1Library.InitData(_host, _ida);
_idav1Lib.createIndex(_token, _INDEX_ID);
/// @notice Airdrops a constant amount if the last
/// airdrop was at least 30 days ago
function airdrop() external {
require(_canAirdrop(), "can not air drop yet");
_idav1Lib.distribute(token, _INDEX_ID, AIRDROP_AMOUNT);
function updateUnits(address subscriber, uint128 units) external {
require(msg.sender == _ADMIN, "unathorized");
_idav1Lib.updateSubscriptionUnits(
function _canAirdrop() internal view returns (bool) {
return lastAirdrop + airdropInterval <= block.timestamp;