IE Contract Design

This document discusses an implementation of an IE contract and some design challenges.

IE Contract Spec

Important Design Challenges

Pull vs Push Payments

Pull vs Push payments is simply a tradeoff between contract security and costs vs user experience. It seems like pull vs push payments will ultimately be a IE design chose by the implementer since there are use cases where using one or the other seems a much better design choice.

Push PaymentsPull Payments
CostGas costs of sending FIL to thousands of users is not trivial. Costs will add up and ultimately there has to be a portion of earnings reduced to gas costs. Even then, there might be participants earnings less FIL than the cost of gas required to send that FIL to them (this is already a scenario happening with Saturn) so operating the IE can come at a loss. No gas costs from the IE side. The gas costs now fall to the user.
SecurityWhen you send FIL to an address, that address can be a contract. That contract can have a fallback function when it receives FIL. A fallback function is a function that is automatically triggered when some event occurs, such as receiving FIL. This fallback function can be customized in a smart contract and it can be customized to something malicious. For example, it can be customized to consume tons of gas or to revert the transaction. This will effectively lock the whole transaction and blocking users from receiving earnings. There are some solutions to this, such as ignoring failed transfers using send instead of transfer . There can also be a function that removes failed transfer participants from the IE and return their earnings to the IE. Still, this introduces a security risk that has to be dealt with very carefully. Pull payments are much more secure. The responsibility of claiming falls to the user and that transaction is isolated. Users cannot simply block each other from claiming.
ScaleThere are limits to transfers and that means we have to batch transfers. Batching costs more money and a lot more time. There might be some clever ways to compress and optimize transactions, but it doesn’t fully resolve the issue. IPC can perform huge carries here. Pull payments also have to be batch deployed. Batching costs more money and a lot more time. There might be some clever ways to compress and optimize transactions, but it doesn’t fully resolve the issue. IPC can perform huge carries here.
IE CompatibilityThis makes it easy to chain multiple IE’s togetherThis makes it rather difficult to chain multiple IE’s together. There could be fallback functions from each IE though, but that adds extra design complexity.
UX Less work for operators and also cost. Might impact folks who want control over their earnings due some reasons (e.g tax)This adds considerable work for the end user. The user has to have initial funds in their wallet to submit a transaction.
IncentivesThis creates a non-ideal incentive for participants. Some participants might earn less than costs in gas to send them their earnings. This works excellently at scale for multinoders. Creates better incentives as nodes have to pay to claim earnings. This dis-incentivizes multinoding and to focus work on one single node.
LegalTODOTODO

Scale

Scale is a hard hitting problem in almost every aspect of IE design.

We have to carefully evaluate which problems IPC subnets can solve for us scale wise.

Here are a list of scale issues to consider:

  • Gas Cost: As number of participants increase, gas costs increase. A suggestion is that participants can only scale if rewards scale as well to ensure gas costs are manageable. That is assuming of course that gas costs increase linearly.
  • Smart Contract limits:
    • Message Size: FVM has a limit on message size, and therefore deployments have to be batched. Batching adds design complexity, increases time, and cost of operating IE rounds.
    • Gas Limits: Transactions on FVM have gas limits, and therefore internally within contracts we cannot have unbounded behaviour, otherwise we risk a transaction going over the gas limit.
    • Storage / Memory Limits: Storage on contracts costs gas. The use of storage should be limited and heavily optimized.
  • Deployment Time: Submitting things to the blockchain is morbidly slow, and as the network grows, we have to make more submissions and hence it takes a lot more time to conclude a deployment.

Future Optimizations

IE Factorization

Our current design leverages one IE smart contract that orchestrates operation of an IE and keeps track of measurements, rounds, etc. Here are the issues with this:

  • Smart contract storage is expensive, the more data you store on a smart contract, the more gas is paid per transaction to perform processing on that data. That means that as more data is added to the contract, the contract becomes more expensive to interact with.
  • Introduces an unbounded data stream into one smart contract. Transactions on contracts are limited by the amount of gas expendable per block. Having unbounded data in one smart contract poses a potential risk of “locking” the smart contract by reaching a point where a transaction on the smart contract requires more gas than the block limit itself.

In general, it is an operational risk to have a smart contract that is exposed to any form of unbounded behaviour.

Proposed Design Change:

The design change here is to have a “factory” IE contract that off loads the data from each IE epoch / round into its own child IE contract.

Additional Problems Addressed:

This design also adds a few “nice to have” features for our IE framework:

  • The Factory IE would naturally act as an interface for our IE contracts. This makes it easy for people to build their own implementations on top.
  • The deployed child contracts give us a fail-safe in the case the parent factory IE contract fails for any reason. IE participants can still claim their rewards by directly interacting with the deployed child contracts which can be queried from the chain.
  • Having a Factory IE gives us more structure to “version” our contracts. A change to the child IE contract signals a minor change and ensures that interactions with the IE still work because the parent interface remains the same. Changes to the Factory IE signal breaking changes to the framework that require changes to how the IE framework is invoked.