Role Rotator: Automate Governance Assignments

This Topic is to discuss Role Rotator Plug-in for SNS and DAO governance.

The Role Roator is the first governance plug-in to take advantage of ICRC-75 and ICRC-104

Reference Motoko Module: GitHub - icdevsorg/af-role-rotator: RoleRotator is a Motoko library that provides functionality to rotate roles (or list memberships) within an ICRC-75 compliant membership list.

Mops: Mops • Motoko Package Manager

Sample Dapp: https://iedms-tqaaa-aaaal-amieq-cai.icp0.io/ (A Role Rotator manages the org.icdevs.lists.king_of_the_hill list, note the canister as admin)

You can change the king of the hill by calling the icrc104_apply_rule endpoint(allowed once every 3 minutes from the anon principal at https://dashboard.internetcomputer.org/canister/aykyz-oyaaa-aaaah-qdsqa-cai with:

icrc75Canister = "nn7ao-eiaaa-aaaap-akjoq-cai";
target_list = "org.icdevs.lists.king_of_the_hill";                     // The list to apply rules on
rule_namespace: "org.icdevs.role_rotator.king";     // Namespace identifying the rule set to apply
//other values can be null

Doing so will swap out the king of the hill for one of the items on the cool kids list.

Tips:

  • Simple class-based implementation. Super easy to add to a governance canister:
   import RoleRotator ".";

   private func qualify(foundMembers: [ListItem], event: ICRC104.HandleRuleEvent, bAwaited: Bool) : async* RoleRotator.QualifyFunctionResponse {

     if(Time.now() < lastCall + (ONE_MINUTE * 3)){
        return #err(#trappable(#apply(#Err(#ExecutionFailed("You must wait 3 minutes between calls")))));
     };

     return #trappable(foundMembers); 
  };

  var _role_rotator : ?RoleRotator.RoleRotator = null;
 
  public shared(msg) func auto_init() : async() {
    D.print("in auto_init");

    
    for(thisStandard in icrc104().supported_standards().vals()){
      ICRC10.register(icrc10, thisStandard);
    };

    icrc104().addAdmin(Principal.fromText("2vxsx-fae"));

    _role_rotator := ?RoleRotator.RoleRotator({
        canister = Principal.fromActor(this);
        icrc75 = null;
        icrc104 = icrc104();
        validator = null;
        qualifyFunction = ?qualify;
        ruleNamespace = "org.icdevs.role_rotator.king";
        eligibleList = "org.icdevs.lists.cool_kids";
    });

Potential use cases:

  • Rotate out a principal on a multi-sig list if it doesn’t sign at least every X Days.
  • Randomly choose a sub-set to get an airdrop
  • Pick a value out of a set of possibilities that rotates every X Minutes.
  • Deadman switches for identities that get executive permissions on DAO Dapps and services.
  • Time-based role assignments (Every three months swap out three DAO members on the grant allocation committee)
  • Attention Based Lotto
  • Leaderboard based promotions
  • Mentor Assignment for new DAO members