HIGH severity: Proposal creation uses incorrect `ERPower::totalPower` as nft power not updated before snapshot. **Description:** If `GovPool` is configured to use `ERC721Power` nft, when the proposal is created it doesn't recalculate the nft power, just [reads](https://github.com/dexe-network/DeXe-Protocol/tree/f2fe12eeac0c4c63ac39670912640dc91d94bda5/contracts/gov/user-keeper/GovUserKeeper.sol#L331)...

Vulnerable code:
it("audit proposal creation uses incorrect ERC721Power totalPower as nft power not updated before snapshot", async () => {
        let powerNftCalcStartTime = (await getCurrentBlockTime()) + 200;

        // required so we can call .toFixed() on BN returned outputs
        ERC721Power.numberFormat = "BigNumber";

        // ERC721Power::totalPower should be zero as no nfts yet created
        assert.equal((await nftPower.totalPower()).toFixed(), "0");

        // so proposal doesn't need to go to validators
        await changeInternalSettings(false);

        // set nftPower as the voting nft
        // need to comment out check preventing updating existing
        // nft address in GovUserKeeper::setERC721Address()
        await impersonate(govPool.address);
        await userKeeper.setERC721Address(nftPower.address, wei("33000"), 33, { from: govPool.address });

        // create a new VOTER account and mint them 5 power nfts
        let VOTER = await accounts(10);
        await nftPower.safeMint(VOTER, 1);
        await nftPower.safeMint(VOTER, 2);
        await nftPower.safeMint(VOTER, 3);
        await nftPower.safeMint(VOTER, 4);
        await nftPower.safeMint(VOTER, 5);

        // advance to the approximate time when nft power calculation starts
        await setTime(powerNftCalcStartTime);

        // save existing nft power after power calculation has started
        let nftTotalPowerBefore = "4500000000000000000000000000";
        assert.equal((await nftPower.totalPower()).toFixed(), nftTotalPowerBefore);

        // advance time; since none of the nfts have collateral deposited
        // their power will decrement
        await setTime((await getCurrentBlockTime()) + 10000);

        // create a proposal which takes a snapshot of the current nft power
        // but fails to update it before taking the snapshot, so uses the
        // old incorrect power
        let proposalId = 2;

        await govPool.createProposal(
          "example.com",
          [[govPool.address, 0, getBytesGovVote(3, wei("100"), [], true)]],
          [[govPool.address, 0, getBytesGovVote(3, wei("100"), [], false)]]
        );

        // verify the proposal snapshot saved the nft totalPower before the time
        // was massively advanced. This is incorrect as the true totalPower is 0
        // by this time due to the nfts losing power. The proposal creation process
        // fails to recalculate nft power before reading ERC721Power::totalPower
        assert.equal((await userKeeper.nftSnapshot(2)).toFixed(), nftTotalPowerBefore);

        // call ERC721::recalculateNftPower() for the nfts, this will update
        // ERC721Power::totalPower with the actual current total power
        await nftPower.recalculateNftPower("1");
        await nftPower.recalculateNftPower("2");
        await nftPower.recalculateNftPower("3");
        await nftPower.recalculateNftPower("4");
        await nftPower.recalculateNftPower("5");

        // verify that the true totalPower has decremented to zero as the nfts
        // lost all their power since they didn't have collateral deposited
        assert.equal((await nftPower.totalPower()).toFixed(), "0");

        // the proposal was created with an over-inflated nft total power
        // GovUserKeeper has a function called updateNftPowers() that is onlyOwner
        // meaning it is supposed to be called by GovPool, but this function
        // is never called anywhere. But in the GovUserKeeper unit tests it is
        // called before the call to createNftPowerSnapshot() which creates
        // the snapshot reading ERC721Power::totalPower
      });